diff --git a/res/css/voice-broadcast/atoms/_VoiceBroadcastControl.pcss b/res/css/voice-broadcast/atoms/_VoiceBroadcastControl.pcss
index bf07157a68..f7cba04870 100644
--- a/res/css/voice-broadcast/atoms/_VoiceBroadcastControl.pcss
+++ b/res/css/voice-broadcast/atoms/_VoiceBroadcastControl.pcss
@@ -25,3 +25,7 @@ limitations under the License.
     margin-bottom: $spacing-8;
     width: 32px;
 }
+
+.mx_VoiceBroadcastControl-recording {
+    color: $alert;
+}
diff --git a/res/css/voice-broadcast/molecules/_VoiceBroadcastRecordingPip.pcss b/res/css/voice-broadcast/molecules/_VoiceBroadcastRecordingPip.pcss
index b01b1b80db..11534a4797 100644
--- a/res/css/voice-broadcast/molecules/_VoiceBroadcastRecordingPip.pcss
+++ b/res/css/voice-broadcast/molecules/_VoiceBroadcastRecordingPip.pcss
@@ -31,5 +31,5 @@ limitations under the License.
 
 .mx_VoiceBroadcastRecordingPip_controls {
     display: flex;
-    justify-content: center;
+    justify-content: space-around;
 }
diff --git a/res/img/element-icons/Record.svg b/res/img/element-icons/Record.svg
new file mode 100644
index 0000000000..a16ce774b0
--- /dev/null
+++ b/res/img/element-icons/Record.svg
@@ -0,0 +1,3 @@
+<svg width="10" height="10" viewBox="0 0 10 10" fill="none" xmlns="http://www.w3.org/2000/svg">
+<circle cx="5" cy="5" r="5" fill="#FF5B55"/>
+</svg>
diff --git a/src/voice-broadcast/audio/VoiceBroadcastRecorder.ts b/src/voice-broadcast/audio/VoiceBroadcastRecorder.ts
index 7f084f3f4a..f84da152ba 100644
--- a/src/voice-broadcast/audio/VoiceBroadcastRecorder.ts
+++ b/src/voice-broadcast/audio/VoiceBroadcastRecorder.ts
@@ -21,6 +21,7 @@ import { VoiceRecording } from "../../audio/VoiceRecording";
 import SdkConfig, { DEFAULTS } from "../../SdkConfig";
 import { concat } from "../../utils/arrays";
 import { IDestroyable } from "../../utils/IDestroyable";
+import { Singleflight } from "../../utils/Singleflight";
 
 export enum VoiceBroadcastRecorderEvent {
     ChunkRecorded = "chunk_recorded",
@@ -65,6 +66,8 @@ export class VoiceBroadcastRecorder
      */
     public async stop(): Promise<Optional<ChunkRecordedPayload>> {
         await this.voiceRecording.stop();
+        // forget about that call, so that we can stop it again later
+        Singleflight.forgetAllFor(this.voiceRecording);
         return this.extractChunk();
     }
 
diff --git a/src/voice-broadcast/components/atoms/VoiceBroadcastControl.tsx b/src/voice-broadcast/components/atoms/VoiceBroadcastControl.tsx
index 238d138698..276282d198 100644
--- a/src/voice-broadcast/components/atoms/VoiceBroadcastControl.tsx
+++ b/src/voice-broadcast/components/atoms/VoiceBroadcastControl.tsx
@@ -14,23 +14,26 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
+import classNames from "classnames";
 import React from "react";
 
 import AccessibleButton from "../../../components/views/elements/AccessibleButton";
 
 interface Props {
+    className?: string;
     icon: React.FC<React.SVGProps<SVGSVGElement>>;
     label: string;
     onClick: () => void;
 }
 
 export const VoiceBroadcastControl: React.FC<Props> = ({
+    className = "",
     icon: Icon,
     label,
     onClick,
 }) => {
     return <AccessibleButton
-        className="mx_VoiceBroadcastControl"
+        className={classNames("mx_VoiceBroadcastControl", className)}
         onClick={onClick}
         aria-label={label}
     >
diff --git a/src/voice-broadcast/components/molecules/VoiceBroadcastRecordingPip.tsx b/src/voice-broadcast/components/molecules/VoiceBroadcastRecordingPip.tsx
index 7178f65965..57e291cae0 100644
--- a/src/voice-broadcast/components/molecules/VoiceBroadcastRecordingPip.tsx
+++ b/src/voice-broadcast/components/molecules/VoiceBroadcastRecordingPip.tsx
@@ -18,11 +18,15 @@ import React from "react";
 
 import {
     VoiceBroadcastControl,
+    VoiceBroadcastInfoState,
     VoiceBroadcastRecording,
 } from "../..";
 import { useVoiceBroadcastRecording } from "../../hooks/useVoiceBroadcastRecording";
 import { VoiceBroadcastHeader } from "../atoms/VoiceBroadcastHeader";
 import { Icon as StopIcon } from "../../../../res/img/element-icons/Stop.svg";
+import { Icon as PauseIcon } from "../../../../res/img/element-icons/pause.svg";
+import { Icon as RecordIcon } from "../../../../res/img/element-icons/Record.svg";
+import { _t } from "../../../languageHandler";
 
 interface VoiceBroadcastRecordingPipProps {
     recording: VoiceBroadcastRecording;
@@ -31,11 +35,22 @@ interface VoiceBroadcastRecordingPipProps {
 export const VoiceBroadcastRecordingPip: React.FC<VoiceBroadcastRecordingPipProps> = ({ recording }) => {
     const {
         live,
-        sender,
+        recordingState,
         room,
+        sender,
         stopRecording,
+        toggleRecording,
     } = useVoiceBroadcastRecording(recording);
 
+    const toggleControl = recordingState === VoiceBroadcastInfoState.Paused
+        ? <VoiceBroadcastControl
+            className="mx_VoiceBroadcastControl-recording"
+            onClick={toggleRecording}
+            icon={RecordIcon}
+            label={_t("resume voice broadcast")}
+        />
+        : <VoiceBroadcastControl onClick={toggleRecording} icon={PauseIcon} label={_t("pause voice broadcast")} />;
+
     return <div
         className="mx_VoiceBroadcastRecordingPip"
     >
@@ -46,6 +61,7 @@ export const VoiceBroadcastRecordingPip: React.FC<VoiceBroadcastRecordingPipProp
         />
         <hr className="mx_VoiceBroadcastRecordingPip_divider" />
         <div className="mx_VoiceBroadcastRecordingPip_controls">
+            { toggleControl }
             <VoiceBroadcastControl
                 icon={StopIcon}
                 label="Stop Recording"
diff --git a/src/voice-broadcast/hooks/useVoiceBroadcastRecording.tsx b/src/voice-broadcast/hooks/useVoiceBroadcastRecording.tsx
index 341283c2ad..ed27119de1 100644
--- a/src/voice-broadcast/hooks/useVoiceBroadcastRecording.tsx
+++ b/src/voice-broadcast/hooks/useVoiceBroadcastRecording.tsx
@@ -52,23 +52,31 @@ export const useVoiceBroadcastRecording = (recording: VoiceBroadcastRecording) =
         const confirmed = await showStopBroadcastingDialog();
 
         if (confirmed) {
-            recording.stop();
+            await recording.stop();
         }
     };
 
-    const [live, setLive] = useState(recording.getState() === VoiceBroadcastInfoState.Started);
+    const [recordingState, setRecordingState] = useState(recording.getState());
     useTypedEventEmitter(
         recording,
         VoiceBroadcastRecordingEvent.StateChanged,
         (state: VoiceBroadcastInfoState, _recording: VoiceBroadcastRecording) => {
-            setLive(state === VoiceBroadcastInfoState.Started);
+            setRecordingState(state);
         },
     );
 
+    const live = [
+        VoiceBroadcastInfoState.Started,
+        VoiceBroadcastInfoState.Paused,
+        VoiceBroadcastInfoState.Running,
+    ].includes(recordingState);
+
     return {
         live,
+        recordingState,
         room,
         sender: recording.infoEvent.sender,
         stopRecording,
+        toggleRecording: recording.toggle,
     };
 };
diff --git a/src/voice-broadcast/models/VoiceBroadcastRecording.ts b/src/voice-broadcast/models/VoiceBroadcastRecording.ts
index f7faa0876e..fccd9d5778 100644
--- a/src/voice-broadcast/models/VoiceBroadcastRecording.ts
+++ b/src/voice-broadcast/models/VoiceBroadcastRecording.ts
@@ -76,11 +76,38 @@ export class VoiceBroadcastRecording
     }
 
     public async stop(): Promise<void> {
+        if (this.state === VoiceBroadcastInfoState.Stopped) return;
+
         this.setState(VoiceBroadcastInfoState.Stopped);
         await this.stopRecorder();
-        await this.sendStoppedStateEvent();
+        await this.sendInfoStateEvent(VoiceBroadcastInfoState.Stopped);
     }
 
+    public async pause(): Promise<void> {
+        // stopped or already paused recordings cannot be paused
+        if ([VoiceBroadcastInfoState.Stopped, VoiceBroadcastInfoState.Paused].includes(this.state)) return;
+
+        this.setState(VoiceBroadcastInfoState.Paused);
+        await this.stopRecorder();
+        await this.sendInfoStateEvent(VoiceBroadcastInfoState.Paused);
+    }
+
+    public async resume(): Promise<void> {
+        if (this.state !== VoiceBroadcastInfoState.Paused) return;
+
+        this.setState(VoiceBroadcastInfoState.Running);
+        await this.getRecorder().start();
+        await this.sendInfoStateEvent(VoiceBroadcastInfoState.Running);
+    }
+
+    public toggle = async (): Promise<void> => {
+        if (this.getState() === VoiceBroadcastInfoState.Paused) return this.resume();
+
+        if ([VoiceBroadcastInfoState.Started, VoiceBroadcastInfoState.Running].includes(this.getState())) {
+            return this.pause();
+        }
+    };
+
     public getState(): VoiceBroadcastInfoState {
         return this.state;
     }
@@ -162,14 +189,14 @@ export class VoiceBroadcastRecording
         await this.client.sendMessage(this.infoEvent.getRoomId(), content);
     }
 
-    private async sendStoppedStateEvent(): Promise<void> {
+    private async sendInfoStateEvent(state: VoiceBroadcastInfoState): Promise<void> {
         // TODO Michael W: add error handling for state event
         await this.client.sendStateEvent(
             this.infoEvent.getRoomId(),
             VoiceBroadcastInfoEventType,
             {
                 device_id: this.client.getDeviceId(),
-                state: VoiceBroadcastInfoState.Stopped,
+                state,
                 ["m.relates_to"]: {
                     rel_type: RelationType.Reference,
                     event_id: this.infoEvent.getId(),
diff --git a/test/voice-broadcast/components/molecules/VoiceBroadcastRecordingPip-test.tsx b/test/voice-broadcast/components/molecules/VoiceBroadcastRecordingPip-test.tsx
index 495d1f109f..8dd6c0a495 100644
--- a/test/voice-broadcast/components/molecules/VoiceBroadcastRecordingPip-test.tsx
+++ b/test/voice-broadcast/components/molecules/VoiceBroadcastRecordingPip-test.tsx
@@ -22,12 +22,12 @@ import { MatrixClient, MatrixEvent } from "matrix-js-sdk/src/matrix";
 import { sleep } from "matrix-js-sdk/src/utils";
 
 import {
-    VoiceBroadcastInfoEventType,
     VoiceBroadcastInfoState,
     VoiceBroadcastRecording,
     VoiceBroadcastRecordingPip,
 } from "../../../../src/voice-broadcast";
-import { mkEvent, stubClient } from "../../../test-utils";
+import { stubClient } from "../../../test-utils";
+import { mkVoiceBroadcastInfoStateEvent } from "../../utils/test-utils";
 
 // mock RoomAvatar, because it is doing too much fancy stuff
 jest.mock("../../../../src/components/views/avatars/RoomAvatar", () => ({
@@ -37,36 +37,49 @@ jest.mock("../../../../src/components/views/avatars/RoomAvatar", () => ({
     }),
 }));
 
+jest.mock("../../../../src/audio/VoiceRecording");
+
 describe("VoiceBroadcastRecordingPip", () => {
-    const userId = "@user:example.com";
     const roomId = "!room:example.com";
     let client: MatrixClient;
     let infoEvent: MatrixEvent;
     let recording: VoiceBroadcastRecording;
+    let renderResult: RenderResult;
+
+    const renderPip = (state: VoiceBroadcastInfoState) => {
+        infoEvent = mkVoiceBroadcastInfoStateEvent(roomId, state, client.getUserId());
+        recording = new VoiceBroadcastRecording(infoEvent, client);
+
+        if (state === VoiceBroadcastInfoState.Paused) {
+            recording.pause();
+        }
+
+        renderResult = render(<VoiceBroadcastRecordingPip recording={recording} />);
+    };
 
     beforeAll(() => {
         client = stubClient();
-        infoEvent = mkEvent({
-            event: true,
-            type: VoiceBroadcastInfoEventType,
-            content: {},
-            room: roomId,
-            user: userId,
-        });
-        recording = new VoiceBroadcastRecording(infoEvent, client);
     });
 
-    describe("when rendering", () => {
-        let renderResult: RenderResult;
-
+    describe("when rendering a started recording", () => {
         beforeEach(() => {
-            renderResult = render(<VoiceBroadcastRecordingPip recording={recording} />);
+            renderPip(VoiceBroadcastInfoState.Started);
         });
 
-        it("should create the expected result", () => {
+        it("should render as expected", () => {
             expect(renderResult.container).toMatchSnapshot();
         });
 
+        describe("and clicking the pause button", () => {
+            beforeEach(async () => {
+                await userEvent.click(screen.getByLabelText("pause voice broadcast"));
+            });
+
+            it("should pause the recording", () => {
+                expect(recording.getState()).toBe(VoiceBroadcastInfoState.Paused);
+            });
+        });
+
         describe("and clicking the stop button", () => {
             beforeEach(async () => {
                 await userEvent.click(screen.getByLabelText("Stop Recording"));
@@ -89,4 +102,24 @@ describe("VoiceBroadcastRecordingPip", () => {
             });
         });
     });
+
+    describe("when rendering a paused recording", () => {
+        beforeEach(() => {
+            renderPip(VoiceBroadcastInfoState.Paused);
+        });
+
+        it("should render as expected", () => {
+            expect(renderResult.container).toMatchSnapshot();
+        });
+
+        describe("and clicking the resume button", () => {
+            beforeEach(async () => {
+                await userEvent.click(screen.getByLabelText("resume voice broadcast"));
+            });
+
+            it("should resume the recording", () => {
+                expect(recording.getState()).toBe(VoiceBroadcastInfoState.Running);
+            });
+        });
+    });
 });
diff --git a/test/voice-broadcast/components/molecules/__snapshots__/VoiceBroadcastRecordingPip-test.tsx.snap b/test/voice-broadcast/components/molecules/__snapshots__/VoiceBroadcastRecordingPip-test.tsx.snap
index 43f7d049ee..7f212d781b 100644
--- a/test/voice-broadcast/components/molecules/__snapshots__/VoiceBroadcastRecordingPip-test.tsx.snap
+++ b/test/voice-broadcast/components/molecules/__snapshots__/VoiceBroadcastRecordingPip-test.tsx.snap
@@ -1,6 +1,6 @@
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
-exports[`VoiceBroadcastRecordingPip when rendering should create the expected result 1`] = `
+exports[`VoiceBroadcastRecordingPip when rendering a paused recording should render as expected 1`] = `
 <div>
   <div
     class="mx_VoiceBroadcastRecordingPip"
@@ -29,7 +29,7 @@ exports[`VoiceBroadcastRecordingPip when rendering should create the expected re
             class="mx_Icon mx_Icon_16"
           />
           <span>
-            @user:example.com
+            @userId:matrix.org
           </span>
         </div>
       </div>
@@ -48,6 +48,89 @@ exports[`VoiceBroadcastRecordingPip when rendering should create the expected re
     <div
       class="mx_VoiceBroadcastRecordingPip_controls"
     >
+      <div
+        aria-label="resume voice broadcast"
+        class="mx_AccessibleButton mx_VoiceBroadcastControl mx_VoiceBroadcastControl-recording"
+        role="button"
+        tabindex="0"
+      >
+        <div
+          class="mx_Icon mx_Icon_16"
+        />
+      </div>
+      <div
+        aria-label="Stop Recording"
+        class="mx_AccessibleButton mx_VoiceBroadcastControl"
+        role="button"
+        tabindex="0"
+      >
+        <div
+          class="mx_Icon mx_Icon_16"
+        />
+      </div>
+    </div>
+  </div>
+</div>
+`;
+
+exports[`VoiceBroadcastRecordingPip when rendering a started recording should render as expected 1`] = `
+<div>
+  <div
+    class="mx_VoiceBroadcastRecordingPip"
+  >
+    <div
+      class="mx_VoiceBroadcastHeader"
+    >
+      <div
+        data-testid="room-avatar"
+      >
+        room avatar: 
+        My room
+      </div>
+      <div
+        class="mx_VoiceBroadcastHeader_content"
+      >
+        <div
+          class="mx_VoiceBroadcastHeader_room"
+        >
+          My room
+        </div>
+        <div
+          class="mx_VoiceBroadcastHeader_line"
+        >
+          <div
+            class="mx_Icon mx_Icon_16"
+          />
+          <span>
+            @userId:matrix.org
+          </span>
+        </div>
+      </div>
+      <div
+        class="mx_LiveBadge"
+      >
+        <div
+          class="mx_Icon mx_Icon_16"
+        />
+        Live
+      </div>
+    </div>
+    <hr
+      class="mx_VoiceBroadcastRecordingPip_divider"
+    />
+    <div
+      class="mx_VoiceBroadcastRecordingPip_controls"
+    >
+      <div
+        aria-label="pause voice broadcast"
+        class="mx_AccessibleButton mx_VoiceBroadcastControl"
+        role="button"
+        tabindex="0"
+      >
+        <div
+          class="mx_Icon mx_Icon_16"
+        />
+      </div>
       <div
         aria-label="Stop Recording"
         class="mx_AccessibleButton mx_VoiceBroadcastControl"
diff --git a/test/voice-broadcast/models/VoiceBroadcastRecording-test.ts b/test/voice-broadcast/models/VoiceBroadcastRecording-test.ts
index 049c03c5a4..3e1965097b 100644
--- a/test/voice-broadcast/models/VoiceBroadcastRecording-test.ts
+++ b/test/voice-broadcast/models/VoiceBroadcastRecording-test.ts
@@ -92,6 +92,25 @@ describe("VoiceBroadcastRecording", () => {
         });
     };
 
+    const itShouldSendAnInfoEvent = (state: VoiceBroadcastInfoState) => {
+        it(`should send a ${state} info event`, () => {
+            expect(client.sendStateEvent).toHaveBeenCalledWith(
+                roomId,
+                VoiceBroadcastInfoEventType,
+                {
+
+                    device_id: client.getDeviceId(),
+                    state,
+                    ["m.relates_to"]: {
+                        rel_type: RelationType.Reference,
+                        event_id: infoEvent.getId(),
+                    },
+                },
+                client.getUserId(),
+            );
+        });
+    };
+
     beforeEach(() => {
         client = stubClient();
         room = mkStubRoom(roomId, "Test Room", client);
@@ -355,6 +374,26 @@ describe("VoiceBroadcastRecording", () => {
                 });
             });
 
+            describe.each([
+                ["pause", async () => voiceBroadcastRecording.pause()],
+                ["toggle", async () => voiceBroadcastRecording.toggle()],
+            ])("and calling %s", (_case: string, action: Function) => {
+                beforeEach(async () => {
+                    await action();
+                });
+
+                itShouldBeInState(VoiceBroadcastInfoState.Paused);
+                itShouldSendAnInfoEvent(VoiceBroadcastInfoState.Paused);
+
+                it("should stop the recorder", () => {
+                    expect(mocked(voiceBroadcastRecorder.stop)).toHaveBeenCalled();
+                });
+
+                it("should emit a paused state changed event", () => {
+                    expect(onStateChanged).toHaveBeenCalledWith(VoiceBroadcastInfoState.Paused);
+                });
+            });
+
             describe("and calling destroy", () => {
                 beforeEach(() => {
                     voiceBroadcastRecording.destroy();
@@ -370,6 +409,32 @@ describe("VoiceBroadcastRecording", () => {
                 });
             });
         });
+
+        describe("and it is in paused state", () => {
+            beforeEach(async () => {
+                await voiceBroadcastRecording.pause();
+            });
+
+            describe.each([
+                ["resume", async () => voiceBroadcastRecording.resume()],
+                ["toggle", async () => voiceBroadcastRecording.toggle()],
+            ])("and calling %s", (_case: string, action: Function) => {
+                beforeEach(async () => {
+                    await action();
+                });
+
+                itShouldBeInState(VoiceBroadcastInfoState.Running);
+                itShouldSendAnInfoEvent(VoiceBroadcastInfoState.Running);
+
+                it("should start the recorder", () => {
+                    expect(mocked(voiceBroadcastRecorder.start)).toHaveBeenCalled();
+                });
+
+                it("should emit a running state changed event", () => {
+                    expect(onStateChanged).toHaveBeenCalledWith(VoiceBroadcastInfoState.Running);
+                });
+            });
+        });
     });
 
     describe("when created for a Voice Broadcast Info with a Stopped relation", () => {