The world number two, who has won the tournament on five occasions, had to withstand a second-set fightback from the tall Croatian before finally prevailing 7-6 3-6 6-3.
After the first 12 games went with serve, Federer came through a tiebreak by a 10-8 scoreline, but Karlovic, who had not beaten the former world number one since 2008, made sure that Federer did not have it all his own way.
The 35-year-old sent down 13 aces, as well as converting a solitary break point, to take the match to a deciding set in front of a pro-Federer crowd.
However, Karlovic dropped serve at the start of the third and that was enough for Federer to move through to the final, where he will play David Goffin.
The Belgian, who has stormed up the world rankings in the second half of 2014, beat Rafael Nadal's conquerer Borna Coric in three sets, eventually overcoming the 17-year-old by a 6-4 3-6 6-3 scoreline.