Gautam Gambhir (88) and Manoj Tiwary (65) provided the mainstay of the India innings with a fourth-wicket partnership of 110 before captain Mahendra Singh Dhoni made 58 from just 38 balls and put on 77 with Irfan Pathan.
And the latter then took five for 61 as Sri Lanka came up just short despite 77 from Lahiru Thirimanne and 72 from Jeevan Mendis.
India openers Gambhir and Ajinkya Rahane put on 29 in five overs and Virat Kohli then joined Gambhir to see the total to 77 before being dismissed for 23.
Rohit Sharma contributed just a solitary boundary but Gambhir found a solid ally in Tiwary.
Gambhir's half-century arrived when a two off Sachithra Senanayake, with the aid of an overthrow, took him to 51 at exactly a run a ball, with seven fours.
The 50 stand came up with only one boundary, gloved over the wicketkeeper's head by Tiwary.
His next was more authentic, driven over extra cover off Mendis, but he escaped a caught-behind appeal off a delivery from Thisara Perera which appeared to take the inside edge.
His half-century came up from 58 balls with a boundary off Nuwan Pradeep but he soon fended a Lasith Malinga bouncer straight to Perera.
Suresh Raina went first ball but Dhoni survived the hat-trick ball and the next three deliveries went to the boundary, the first via the India captain's helmet.
Gambhir popped Senanayake to Malinga at point but Pathan was quickly into his stride with two boundaries.
Dhoni took three fours in a row off Perera, the second of which brought up a 50 partnership in 40 balls, and reached his half-century by heaving the same bowler for his only six.
He top-edged to keeper Dinesh Chandimal to give Malinga his 200th ODI wicket but Pathan remained on 29 not out at the end.
Upul Tharanga gave Sri Lanka a racing start with 31 from 21 balls, putting on 48 with Thirimanne after Tillakaratne Dilshan was dismissed for a duck.
Chandimal and Angelo Mathews went cheaply and, after Chamara Kapugedera followed, it was left to Thirimanne and Mendis to rebuild from 102 for five.
They made very steady progress to a fifty partnership before Thirimanne hammered Rohit Sharma to the mid-wicket boundary and reached his half-century in the next over, from 81 balls with five boundaries.
He hit Tiwary for two sixes in the spinner's first over and added another off Khan as the century stand came up, but was then dropped by Dhoni before being shambolically run out later in the same over.
Perera and Mendis tried to keep the momentum going and the latter reached a 71-ball half-century with only his fourth boundary, off Ravichandran Ashwin.
The partnership moved rapidly to 48 before both batsmen were dismissed within four balls. Perera holed out after a useful 18 and the terminal blow came when Mendis, having made 72, nicked Pathan to Dhoni.
Pathan clean bowled Senanayake with the final ball of his spell to pick up his fifth wicket and though Malinga crashed two boundaries, he was then caught on the boundary to end Sri Lanka's valiant challenge.