The controller has a register for the program counter that keeps track of the address where the next-to-be-executed instruction is stored. (This register is also written when a jump is executed.)
The controller has an interrupt vector (or sometimes more than one, dependent on the type of interrupt), which is the address where the ISR is stored. This address is always the same - it's like the reset vector, where the program starts.
(Often, there's a jump instruction stored at this vector that jumps to the actual code to execute, since the space at the vector is not enough to store the whole procedure. However, the important thing is that the ISR is always located at the same position.)
When an interrupt occurs, there's some dedicated hardware in the controller that writes the program counter with the interrupt vector. Then, when the controller reaches the next instruction cycle, it fetches the instruction from the address that is pointed to by the program counter (so, the interrupt vector).
(In one instruction cycle of the controller there are different tasks it performs: it fetches the next instruction from the address pointed to by the program counter; it increases the program counter; it decodes the instruction, and executes it.)