Rangers needed a late goal from substitute Nacho Novo to give them victory over a St. Mirren side who looked out of it at half-time, but fought back determinedly.
Early slick movement from the visitors came to nothing and Saints scored in their first attack. Simon Lappin swung over a fine deep cross from the left and John Sutton rose to fire a header past Lionel Letizi.
The equaliser came when Charlie Adam thumped a fearsome free-kick past Tony Bullock, and Rangers went ahead when Thomas Buffel stroked the ball past Bullock after gliding through Saints' rearguard from Kris Boyd's pass.
Bullock denied Boyd but Rangers were unable to build on their superiority, based around Barry Ferguson and Brahim Hemdani.
On the hour mark, Bullock saved Boyd's drive with his foot, before the striker had a penalty claim waved away after tangling with David van Zanten.
Saints were gaining in confidence and Sutton's flicked header tested Letizi, before the referee awarded the hosts a penalty when Julien Rodriguez was adjudged to have pushed Mark Corcoran. Sutton scored with a low shot.
Ferguson headed a Stephen Smith cross straight at Bullock, but Novo netted the winner five minutes from the end, slamming the ball into the net after Bullock had blocked Adam's drive.
The three points keep the Gers in the title hunt, although they remain ten points adrift of Celtic.