The annulled branch instruction causes the instruction in the delay slot -- the instruction after the branch -- to be ignored if the branch is not taken.
Why would this be important? Because normally, the instruction after the branch is executed, even if the branch is taken. This is because there are two program counters, PC and NPC. PC, which indicates the instruction being executed, is updated to NPC, which is PC + 4, at the same time as NPC is being updated to the target of the branch instruction. So because of the timing of these events, the next instruction has to be loaded. Rather than just throw that cycle away, it's more profitable to use that cycle if we can. We would then just make that instruction part of the loop.
loop: someOp
someOtherOp
branch loop ;
delayslotOp ; will actually be executed, before someOp, after branch
If we can't use the instruction slot after the branch, then we stick a nop in there, and do nothing on that cycle.
So why then have different instructions with annulled and non-annulled branch options? To give us the choice of what happens on exit from the loop. If we've made the delay slot part of the loop activity, we might not want that op executed upon leaving from the loop. Therefore, we'd add ",a" to the end of the branch instruction.
This page has some nice examples.