Swann (4-34), playing his fourth one-dayer since making his debut in 2000, built on the efforts of pacemen Ryan Sidebottom and Stuart Broad to boost his team's hopes of gaining a lead in the five-match series, currently tied 1-1.
Tillakaratne Dilshan top-scored with a gutsy 70, just one day after being dropped from the squad for next month's tour of Australia. He hit six fours in his 84-ball knock for his first half-century in 15 matches.
Sidebottom (3-19) and Broad (2-26) jolted Sri Lanka with four early wickets on a slow pitch before Swann kept pressure in the middle overs with a tidy line and length.
Sri Lanka, electing to bat, struggled to score freely against England's pace-spin combination. They were reduced to 42-4 in the opening 15 overs in a match reduced to 48-overs-a-side due to rain.
The hosts were under pressure after losing openers Upul Tharanga (15) and Sanath Jayasuriya (11) in Sidebottom's opening spell.
Tharanga was bowled off-stump by a delivery that cut in sharply, while veteran Jayasuriya was caught by Swann at deep square-leg while pulling.
Broad struck with his first delivery when he had Sri Lanka skipper Mahela Jayawardene (two) caught by Paul Collingwood at point and then had Kumar Sangakkara (nine) caught behind.
Sangakkara 'walked' even though wicket-keeper Phil Mustard and the bowler initially had not appealed.
Dilshan kept the England attack at bay before being the ninth man out in the 41st over. He added 46 valuable runs for the ninth wicket with Dilhara Fernando.