Efe Ambrose’s second goal in as many games gave Celtic the lead before the break, but they missed the chance to move 21 points clear when Nigel Hasselbaink levelled late on.
The Hoops had quickly displayed their attacking threat as Kris Commons sent Gary Hooper clear, but the striker’s weak effort was saved by Alan Mannus.
Hooper spurned another chance soon afterwards when he seized on Frazer Wright’s blunder and sent a scuffed effort at Mannus.
St Johnstone were struggling to hold the visitors at bay and Lassad Nouioui headed past the far post from Emilio Izaguirre’s cross.
Mehdi Abeid gave Saints rare respite when he fired when from the edge of the box, but Celtic remained on top and only fine saves from Mannus kept out shots from Ledley and Lassad.
Mannus’ one-man resistance was broken in the 37th minute when Commons played a short corner to Izaguirre and his cross was headed home by Ambrose.
Celtic tried to increase their lead after the break as Victor Wanyama tested Mannus, but at the other end Saints had a goal ruled out for offside after Steven MacLean turned in Abeid’s free-kick.
The linesman’s flag again frustrated the hosts as Wright’s header was also chalked off when he was ajudged to have strayed offside.
But St Johnstone’s attacking efforts were finally rewarded when substitute Hasselbaink (82) turned neatly and sent a curling shot into the top corner.
The Hoops nearly made an instant response as another replacement James Forrest drove the ball past the post.
But Saints ended the game on top and Patrick Cregg saw his shot saved by Forster before David McCracken missed the chance to grab a winner when he nodded wide from close range.