Richards converted from 12 yards after Marvin Morgan was brought down in the area by Ben Davies to leave Preston without a home win in the league since September.
The Lilywhites looked like they were going to end that run when Stuart Beavon scored his ninth of the season after 43 minutes, but Jon Taylor equalised 20 minutes later and Richards wrapped it up.
In a first half of few chances, Beavon missed the opportunity to put the hosts in front after 23 minutes, volleying over from Jack King's header.
He made amends in style, though, just before the break when he unleashed a swerving 30-yard strike that flew past Chris Weale.
Shrewsbury were level through Taylor's crashing drive from just inside the area after substitute Paul Parry's pass.
Graham Cummins was then denied by Cameron Gayle's headed goal-line clearance, but with the game heading for a draw Richards was given the chance to win it and made no mistake.