The Swiss survived a second-set scare before coming through 7-6 (7/4) 3-6 7-5 in just under two hours.
"It was extremely difficult," Federer said on the ATP website.
"I started really well. I thought we were both hitting the ball well in the first set and not giving each other that many chances.
"It went down to the wire."
Federer will play qualifier Federico Delbonis in the last four after he completed a fine comeback against Fernando Verdasco, the 14th seed.
Delbonis saved two match points on his way to a 6-7 (5/7) 7-6 (8/6) 6-4 victory.
The other semi-final will be between Italy's Fabio Fognini and Spain's Nicolas Almagro.
Fognini saw off Tommy Haas 6-2 6-4, while Almagro overcame Juan Monaco 4-6 6-0 6-3.