diff --git a/.github/workflows/wheel-builder.yml b/.github/workflows/wheel-builder.yml
index 31802e79551e84c147335cbb2bfd99c2faf3172d_LmdpdGh1Yi93b3JrZmxvd3Mvd2hlZWwtYnVpbGRlci55bWw=..eb3b5bca1c8544fce0b66f59a98de81422ba84f3_LmdpdGh1Yi93b3JrZmxvd3Mvd2hlZWwtYnVpbGRlci55bWw= 100644
--- a/.github/workflows/wheel-builder.yml
+++ b/.github/workflows/wheel-builder.yml
@@ -7,6 +7,12 @@
       version:
         description: The version to build
         required: false
+  pull_request:
+    paths:
+      - .github/workflows/wheel-builder.yml
+      - setup.py
+      - setup.cfg
+      - pyproject.toml
 
 
 jobs:
@@ -15,14 +21,25 @@
     strategy:
       matrix:
         PYTHON:
-          - {VERSION: "cp36-cp36m", ABI_VERSION: 'cp36'}
-        CONTAINER:
-          - {IMAGE: "cryptography-manylinux2014:x86_64", NAME: "manylinux2014"}
-          - {IMAGE: "cryptography-manylinux_2_24:x86_64", NAME: "manylinux_2_24"}
-          - {IMAGE: "cryptography-manylinux_2_28:x86_64", NAME: "manylinux_2_28"}
-          - {IMAGE: "cryptography-musllinux_1_1:x86_64", NAME: "musllinux_1_1"}
-    name: "${{ matrix.PYTHON.ABI_VERSION }} ${{ matrix.CONTAINER.NAME }}"
-    container: ghcr.io/pyca/${{ matrix.CONTAINER.IMAGE }}
+          - { VERSION: "cp36-cp36m", ABI_VERSION: 'cp36' }
+          - { VERSION: "pp37-pypy37_pp73" }
+          - { VERSION: "pp38-pypy38_pp73" }
+          - { VERSION: "pp39-pypy39_pp73" }
+        MANYLINUX:
+          - { CONTAINER: "cryptography-manylinux2014:x86_64", NAME: "manylinux2014" }
+          - { CONTAINER: "cryptography-manylinux_2_24:x86_64", NAME: "manylinux_2_24" }
+          - { CONTAINER: "cryptography-manylinux_2_28:x86_64", NAME: "manylinux_2_28" }
+          - { CONTAINER: "cryptography-musllinux_1_1:x86_64", NAME: "musllinux_1_1" }
+        exclude:
+          # There are no readily available musllinux PyPy distributions
+          - PYTHON: { VERSION: "pp37-pypy37_pp73" }
+            MANYLINUX: { NAME: "musllinux_1_1", CONTAINER: "cryptography-musllinux_1_1:x86_64" }
+          - PYTHON: { VERSION: "pp38-pypy38_pp73" }
+            MANYLINUX: { NAME: "musllinux_1_1", CONTAINER: "cryptography-musllinux_1_1:x86_64"}
+          - PYTHON: { VERSION: "pp39-pypy39_pp73" }
+            MANYLINUX: { NAME: "musllinux_1_1", CONTAINER: "cryptography-musllinux_1_1:x86_64"}
+    name: "${{ matrix.PYTHON.VERSION }} for ${{ matrix.MANYLINUX.NAME }}"
+    container: ghcr.io/pyca/${{ matrix.MANYLINUX.CONTAINER }}
     steps:
       - uses: actions/checkout@v3.1.0
         with:
@@ -34,7 +51,12 @@
       - name: Make sdist
         run: .venv/bin/python setup.py sdist
       - run: tar zxvf dist/bcrypt*.tar.gz && mkdir tmpwheelhouse
-      - run: cd bcrypt* && ../.venv/bin/python setup.py bdist_wheel --py-limited-api=${{ matrix.PYTHON.ABI_VERSION }} && mv dist/bcrypt*.whl ../tmpwheelhouse
+      - name: Build the wheel
+        run: |
+          if [ -n "${{ matrix.PYTHON.ABI_VERSION }}" ]; then
+              PY_LIMITED_API="--py-limited-api=${{ matrix.PYTHON.ABI_VERSION }}"
+          fi
+          cd bcrypt* && ../.venv/bin/python setup.py bdist_wheel $PY_LIMITED_API && mv dist/bcrypt*.whl ../tmpwheelhouse
         env:
           RUSTUP_HOME: /root/.rustup
       - run: auditwheel repair tmpwheelhouse/bcrypt*.whl -w wheelhouse/
@@ -46,7 +68,7 @@
       - run: mv wheelhouse/bcrypt*.whl bcrypt-wheelhouse/
       - uses: actions/upload-artifact@v1
         with:
-          name: "bcrypt-${{ github.event.inputs.version }}-${{ matrix.CONTAINER.NAME }} -${{ matrix.PYTHON.ABI_VERSION }}"
+          name: "bcrypt-${{ github.event.inputs.version }}-${{ matrix.MANYLINUX.NAME }} -${{ matrix.PYTHON.ABI_VERSION }}"
           path: bcrypt-wheelhouse/
 
   macos:
diff --git a/README.rst b/README.rst
index 31802e79551e84c147335cbb2bfd99c2faf3172d_UkVBRE1FLnJzdA==..eb3b5bca1c8544fce0b66f59a98de81422ba84f3_UkVBRE1FLnJzdA== 100644
--- a/README.rst
+++ b/README.rst
@@ -51,6 +51,11 @@
 Changelog
 =========
 
+4.1.0
+-----
+
+* We now build PyPy ``manylinux`` wheels.
+
 4.0.0
 -----