Sri Lanka, resuming after lunch on the fourth day at 292-3, moved to 392-5 in their second innings by tea, an overall lead of 299 with five wickets in hand.
Left-handed Sangakkara followed his 92 in the first innings with an attractive 137 not out as the hosts looked to set England an imposing fourth innings target at the Asgiriya stadium.
It was Sangakkara's 16th Test century -- the sixth in his last 10 innings -- and made him only the ninth batsman in history to score a hundred against all the other nine Test-playing nations.
But he almost did not get there as Ian Bell at first slip dropped an easy catch off left-arm seamer Ryan Sidebottom when the batsman edged a rising ball on 98.
Sangakkara took a single to move to 99 and then drove James Anderson uppishly past Ravi Bopara in the covers to reach three-figures with his 14th boundary.
He has so far hit 19 fours.
Sangakkara celebrated his hundred with a powerful cut off Anderson to the cover fence and partner Chamara Silva joined in with two consecutive fours in the same over.
Sangakkara and captain Mahela Jayawardene put on 122 for the third wicket in the morning session after coming together at the fall of Michael Vandort's wicket at 166-2 the previous evening.
Jayawardene made amends for falling for one the first time with a stroke-filled 65, his 30th Test half-century that was studded with nine boundaries.
The Sri Lankan captain was dismissed just before lunch when he was caught down the leg-side by wicket-keeper Matt Prior, who was standing up to the stumps to fast bowler Matthew Hoggard.
Silva increased England's misery by adding 71 in 75 minutes for the fourth wicket, himself making 37 before falling leg-before to spinner Monty Panesar.
Jehan Mubarak was removed for nine, but Prasanna Jayawardene kept Sangakkara company at tea on three.
Sri Lanka's Australian coach Trevor Bayliss had said on Monday that England could find 250 runs tough to chase on the slow wicket that is expected to crack up.
Sri Lanka made 188 in their first innings and England replied with 281, with Muttiah Muralitharan grabbing six wickets on the way to surpassing retired Australian Shane Warne's world record tally of 708 on Monday.