England fought back to finish the fourth day on 267-8 and lead Sri Lanka by 389 runs in the first Test at Lord's.
With one day left, the Sri Lankans will have to pass the highest successful run chase at Lord's of 344, achieved by the West Indies in 1984. An overnight declaration from England looks highly likely, as it will seek to take 10 wickets in the final day.
When Matt Prior was caught by Kumar Sangakkara at gully off the bowling of Nuwan Kulasekara, the hosts were struggling on 121-6, but Ballance and Chris Jordan put on a valuable partnership of 78 for the seventh wicket.
It was a stand which turned the test back in England's favor, according to Sri Lanka captain Angelo Mathews. England had gone to tea on 117-5.
"Until Ballance and Jordan got together we had a chance (of winning)," Mathews said. "We need to bat sensibly because they have got a healthy lead. The wicket is playing up and down, so we will assess the conditions first tomorrow and see how it goes."
Jordan was dismissed by Rangana Herath for 35 with England on 199 and Stuart Broad made a quick contribution of 24 from 18 balls. Ballance brought up his century by smashing Herath for a six over midwicket, something which was out of keeping with the patient nature of his innings as he guided England away from trouble.
The 36-year-old Herath was Sri Lanka's leading wicket taker after finding some turn in the wicket and finished the day with figures of 4-95. Shaminda Eranga, who dismantled England's upper batting order by removing Alistair Cook (28), Sam Robson (19) and Ian Bell (9) for figures of 3-63, also found some movement. It will encourage England's bowlers going into the final day.
Earlier, Mathews made 102 as Sri Lanka were bowled out for 453, 122 runs behind England's first innings total of 575-9 declared. The tourists resumed on 415 and James Anderson made the breakthrough for England, removing Herath on two.
Mathews, resuming on 79, then reached three figures by whipping Anderson for four through mid-off.
It took him 171 balls to reach his century, which included 12 fours, but the Sri Lanka captain faced only one more delivery as Liam Plunkett dismissed him lbw with a yorker. Mathews appealed, hoping that he had got his bat to the ball first, but replays upheld umpire Bowden's decision.
Chris Jordan then removed Nuwan Pradeep to wrap up the tourists' first innings with his third wicket. Pradeep hit his stumps after being struck on the shoulder by the ball and there was some concern for him when he remained down on the ground after clattering into his stumps.
But he eventually got to his feet, jogged back to the pavilion and managed to bowl two overs at England's openers before the lunch break.