The "normal" way to execute code goes like this: There is a program counter (PC). The processor executes the instruction pointed to by the program counter. If that instruction is an unconditional branch, or a conditional branch and the condition is true, then the program counter is set to the destination of the branch. Otherwise, the program counter is increased by the length of the instruction.
With out-of-order execution, it seems to the programmer as if everything happened exactly the "normal" way. But internally, the processor can re-order instructions, as long as the observed behaviour is unchanged. An example: You have three instructions: Read X from memory, add X to Y, set Z to 0. Since "Read X from memory" takes a long time, and "add X to Y" must wait until X has been read, the processor executes "set Z = 0" before "add X to Y". But the behaviour that the programmer observes is the same. If they check what the value of Y is, that check is itself an instruction that waits until "add X to Y" is executed, so the value will look fine.
Delayed branches don't work like that. They change the semantics of the code in a defined way. Where I said earlier "if the instruction is a conditional branch and the condition is true, the program counter is set to the destination of the branch", that is not true. Instead, the program counter is set to the destination of the branch after the next instruction has been executed.
With delayed branches, instructions are still executed in order, but the meaning of "in order" has changed. If you have instructions (A, B, C, conditional branch, D, E, F) and the instructions at the destination of the conditional branch are X, Y, Z then instead of the usual order A, B, C, X, Y, Z the order is A, B, C, D, X, Y, Z. And these instructions are executed in order (they might actually be executed out of order, but except for the difference in speed you wouldn't notice).