Federer was up a service break twice in the second set but couldn't close out the victory. He lost serve five times and committed 39 unforced errors.
Nishikori's opponent Friday will be three-time champion Novak Djokovic, who benefited from an erroneous call in the pivotal game to beat Andy Murray 7-5, 6-3.
Nishikori will be playing in only his second ATP Masters 1000 semifinal, and his first in 2½ years. He advanced by breaking Federer five times, including in the final game.
"I thought I really played well, especially in the third set," Nishikori said. "I was hitting balls deep and striking well. Everything was going well."
Federer was the runner-up to Djokovic at Indian Wells two weeks ago, and said he's pleased with his start to the year despite the latest loss.
"I just couldn't find my rhythm on the serve today, which was surprising," Federer said. "It's a bit frustrating, but Kei did well to stay with me. He was more consistent in the second and third, and in the end it's to his credit."
The point in question for Murray occurred at the start of the 12th game with him serving at 5-6. Djokovic charged forward to volley a short ball and hit it for a winner.
Murray argued -- and TV replays confirmed -- he should have be awarded the point because Djokovic's racket was on the far side of the net when he hit the ball. Chair umpire Damian Steiner declined to change his call, and such rulings can't be appealed for video review.
An irritated Murray briefly discussed the matter with Djokovic.
"I went and asked Novak, and he told me he was over the net," Murray said.
"Look, it might be my mistake," Djokovic said. "I think I crossed the net with the racket. I didn't touch the net. Maybe the rule is that you are not allowed to pass on his side with the racket. I'm not sure. You tell me."
That is indeed the rule.
"Obviously, that distracted him mentally, and after that he gave the set away," Djokovic said.