1. Sometimes more efficient code (state machines can make really good use of this pattern)
2. There is no structured programming equivalent or no good structured programming equivalent within the language.
For (2), you see it a lot in the Linux kernel (and similar) code where it's utilized for early exits. Where a language like Go might use a defer statement or Java and similar might use a try/catch/finally and exceptions, C would put a bunch of clean up statements after one or more labels at the end of the function before the single return. Which label you go to (if you use more than one) would depend on how far into the function you've gotten.
My emphasis. C is barely younger than Dijkstra's letter, and by comparison to a modern language it is impoverished when it comes to structural flow control. Still, you won't find modern C programmers arguing that they don't see any use for while loops, or that switch is pointless because they could just use longjmp.
when used properly it should be really obvious what it's doing, where it's going, and shouldn't produce any weird side effects. jumping into another function or module or file isn't good.
Otherwise you have to free all the buffers in every place where an error might happen, and you will most likely forget to free some or double-free.