Resuming on a precarious 21-3 in the bowler-dominated weather-hit contest, the visitors needed a string of cameos from their middle and lower-order batsmen to score 274 in their second innings.
In their first test since batting great Kumar Sangakkara retired, Sri Lanka lost opener Upul Tharanga in the first over and were reeling at 67-3 at the close.
Opener Kaushal Silva (24) and skipper Angelo Mathews (22) were at the crease with the hosts still needing 319 runs for an improbable victory.
Having taken a 111-run first-innings lead, India consolidated their position in the first two sessions at the Sinhalese Sports Club to virtually bat Sri Lanka out of the contest.
Dhammika Prasad bowled with characteristic hostility but Nuwan Pradeep drew first blood, dismissing India captain Virat Kohli (21) who again succumbed to his penchant for pushing at deliveries outside the off-stump.
Rohit Sharma (50) looked more convincing, hitting Pradeep for back-to-back boundaries and bringing up his fourth test fifty before pulling a short Prasad delivery to fine leg.
Stuart Binny (49) came up with a more eventful knock — playing some risky shots, surviving a stumping opportunity, being hit on the helmet by Prasad and eventually falling agonisingly short of his second test fifty.
Debutant Naman Ojha (35) and Amit Mishra (39) frustrated Sri Lanka while Ravichandran Ashwin (58) registered his fifth test fifty before being the last man out.
Sri Lanka wobbled early in their chase with Ishant Sharma dismissing Tharanga before Umesh Yadav sent back Dimuth Karunaratne — both caught by wicketkeeper Naman Ojha for nought.
Ishant, who had an animated altercation with Prasad earlier in the day, also dismissed Dinesh Chandimal before giving the batsman a send-off, an act that earned him a 65 percent match fee fine in the first test.