Three things, one spot on the whiteboard
These three get confused because they sit in the same place on a whiteboard, in front of your backends. What separates them is what each one knows.
A load balancer knows about servers. It spreads traffic across identical copies of one thing and checks whether they are alive.
The simple kind sees only addresses and ports, and the smarter kind reads HTTP and routes on paths, which blurs the line. Even then it holds no opinion about your API, your users or your tokens. It is capacity plumbing.
An API gateway knows about your API. It routes between different services, validates identity, limits each consumer, and reshapes requests.
Run both, which is what actually happens. Balancers in front of your redundant gateway instances, and more balancing behind the gateway across each service's copies. Gateway or load balancer is usually the wrong question, because the answer is gateway and load balancers, at different layers.
Backend for frontend
A backend for frontend knows about one specific client. Each client type gets its own thin backend, one for the iOS app and one for the web app, each owned by the team that builds that client.
Watch how differently those two behave. The mobile one merges four service calls into one compact answer, because cell networks punish round trips. The web one returns richer payloads, because a desktop can take them.
Put your aggregation logic here rather than in the gateway, because it changes with a client's screens and not with your platform.
Assemble a workable stack for a mid-size company. A CDN and denial-of-service layer at the edge, one general-purpose gateway doing auth and rate limiting, and a backend per frontend only where client needs genuinely diverge.
Time that last one properly. Adding one per client on day one is ceremony. Adding one when the mobile team's third aggregation request hits your gateway backlog is judgement.
Worked example
SoundCloud is the origin story. Around 2013, as they broke apart their monolith, every client (web, iOS, Android, embedded players) hit one shared API, and each feature negotiation dragged in every client team, since a payload change for mobile could break the web player. Phil Calcado's team introduced a backend per client: the iOS BFF could reshape, trim, and merge responses for its app without asking anyone. Ownership followed: the mobile team shipped their BFF on their own schedule. The pattern spread industry-wide because the pain is universal. Netflix landed on a similar shape independently, letting device teams write their own server-side adapters, since a smart TV from 2015 and a modern browser want very different payloads from the same platform.