Christian Nade ended his nine-month goal drought in emphatic style in the first half, but Derek McInnes' side were a different team after the interval and equalised through top scorer Collin Samuel's header.
Referee Stevie O'Reilly then controversially sent off Jose Goncalves with a straight red card and Saints took advantage to claim victory through former Hibernian striker Johansson three minutes from time.
Hearts are now winless in six Scottish Premier League matches and have slipped below St Johnstone into the relegation mix.
Jambos boss Csaba Laszlo made two changes with Gary Glen and David Obua in for Andrew Driver and Arvydas Novikovas. Graham Gartland failed to shake off a shoulder problem for the visitors and Stuart McCaffrey deputised.
Hearts made a fast start with Glen's early effort from distance held by Graeme Smith.
The Perth defence then appeared lucky to get away with an apparent passback after Danny Grainger cushioned the ball to Smith just five yards from goal, but referee O'Reilly was unmoved.
It was 12 minutes before Saints offered a threat but Filipe Morais' angled shot was easy for Janos Balogh.
McInnes felt his team had a decent penalty claim in the 20th minute after Goncalves caught Kenny Deuchar with a boot on the head, but O'Reilly appeared to miss the incident.
The home supporters were becoming frustrated at the lack of entertainment as Hearts struggled to create openings.
On the half-hour mark, Glen again tried his luck from long range but Smith was behind the shot.
Yet, out of the blue, Nade broke the stalemate with a wonderful goal on 35 minutes. The Frenchman unleashed a sweet 25-yard strike that whistled across Smith into the bottom right corner - his first goal since February.
Immediately after the restart, Saints failed in a second penalty claim after Murray Davidson was felled but the hosts were now in confident mood.
Jason Thomson toe-poked just wide from distance and then Smith made a fine reflex save from Obua. Balogh also had to look smart to deny Morais after he latched on to a Deuchar flick-on.
McInnes made a half-time switch with Kevin Moon replacing Chris Millar. The change helped the visitors resume more positively but Hearts succeeded in defending their dangerous set-pieces.
Moon then became first player to be yellow-carded after a late challenge on Lee Wallace.
But matters swiftly improved for the McDiarmid Park side when they grabbed the equaliser on the hour.
Excellent work from Morais on the left saw him twist past Thomson and plant a cross on the head of Samuel who nodded home for his seventh of the season.
Saints, now much-improved, replaced Morais with Liam Craig after 65 minutes while Hearts' David Witteveen came on for Glen.
Tynecastle captain Michael Stewart saw his free-kick drift over before Black was cautioned for a foul on Grainger.
Samuel then came within inches of a second as his searing, angled drive flew across Balogh's goal.
Jody Morris went even closer on 76 minutes as his close-range volley from a Craig cross was brilliantly blocked by Balogh.
Controversy raged seconds later when Hearts were reduced to 10 men. O'Reilly brandished a straight red card at Goncalves for a high boot challenge on Craig, but the decision looked harsh and Hearts vented their anger.
McInnes' charges sought to use their man advantage and had a fine chance when Dave Mackay picked out Craig at the back post but the midfielder's weak effort was deflected over.
McInnes threw on Johansson in search of victory and it proved inspired within seconds.
After Obua failed to usher the ball out of play, Mackay fed Morris whose cross found Craig. His header back across goal then allowed Johansson an easy tap-in to seal victory on 87 minutes.