Pakistan, trailing 1-0 in the three-match series, took advantage of Sri Lankan captain Mahela Jayawardene's surprise decision to field first on a good batting track at the Sinhalese Sports Club.
Hafeez led the Pakistani charge with his fifth Test century - and the first after 10 innings - as the tourists moved to a commanding 334 for one by stumps on the opening day.
The Pakistan vice-captain has put on 256 runs for the unbroken second wicket with Azhar Ali (92 not out) after sharing an opening stand of 78 with Taufeeq Umar (65).
It was the first time since making 379-4 against India in Faisalabad in 2006 that Pakistan scored over 300 runs on the first day of a Test match.
The century helped Hafeez overcome the disappointment of losing the first Test in Galle by 209 runs, where he led Pakistan in the absence of the banned Misbahul Haq.
The all-rounder had been under pressure to retain his place in the Test side after a barren run of 10 innings since making his previous best of 143 against Bangladesh in Chittagong last year.
But Hafeez answered his critics in style, smashing 18 boundaries and a six off Suraj Randiv that sailed over the mid-wicket fence.
Azhar was content to play second fiddle at the other end, scoring just six fours, as the second-wicket pair laid the foundation for a big first innings total.
Azhar will resume on Sunday needing just eight runs to complete his third Test century.
Hafeez earned a lucky break just before tea when he was caught down the leg-side by wicket-keeper Prasanna Jayawardene, but television replays confirmed Angelo Mathews had sent down a no-ball.
When Hafeez was on 171, umpire Simon Taufel turned down Rangana Herath's confident appeal for a catch at the wicket even as television replays indicated the ball may have gone off the bat.
Hafeez took time to settle down, making only 20 till lunch, before opening out after the break with attractive strokeplay on both sides of the wicket.
He had scored only 12 when Taufeeq raced to his 14th Test half-century in the 18th over with two successive boundaries off Mathews.
Taufeeq fell just when he had mastered the Sri Lankan attack, edging an intended cut off Mathews to the wicket-keeper.
Hafeez began the post-lunch session by sweeping Herath for two fours to bring up Pakistan's 100 and then drove Nuwan Kulasekara to the point fence to reach his eighth half-century.
Misbah returned to lead Pakistan after missing the Galle Test due to a one-match ban for slow over-rates. Middle-order batsman Mohammad Ayub was dropped to accommodate the skipper.
But the tourists were without frontline seamer Umar Gul, who was ruled out with an ankle injury. He was replaced by fast bowler Aizaz Cheema.
Sri Lanka retained the same side that won the first Test to take the lead in the three-match series.
COMMENTS (5)
Comments are moderated and generally will be posted if they are on-topic and not abusive.
For more information, please see our Comments FAQ
Responsible play by all 3 batsmen but how come everyone now is lauding this one performance. The pitch they are playing on is totally flat...so let the SriLankans bat and then laud them too!
Jiye Pakistan! Hafeez has the ability to become the world's best all-rounder.
m hafeez congrtulation
Bravo Pakistan; good comback