diff --git a/swh/web/browse/snapshot_context.py b/swh/web/browse/snapshot_context.py
--- a/swh/web/browse/snapshot_context.py
+++ b/swh/web/browse/snapshot_context.py
@@ -85,6 +85,9 @@
             branches_from=branch_name,
             branches_count=1,
             target_types=["revision", "alias"],
+            # pull request branches must be browsable even if they are hidden
+            # by default in branches list
+            branch_name_exclude_prefix=None,
         )
         snp_branch, _, _ = process_snapshot_branches(snp)
         if snp_branch and snp_branch[0]["name"] == branch_name:
diff --git a/swh/web/tests/browse/views/test_origin.py b/swh/web/tests/browse/views/test_origin.py
--- a/swh/web/tests/browse/views/test_origin.py
+++ b/swh/web/tests/browse/views/test_origin.py
@@ -1297,3 +1297,22 @@
         client, url, status_code=200, template_used="browse/branches.html"
     )
     assert_not_contains(resp, "refs/pull/")
+
+
+@given(origin_with_pull_request_branches())
+def test_browse_pull_request_branch(client, archive_data, origin):
+    snapshot = archive_data.snapshot_get_latest(origin.url)
+    pr_branch = random.choice(
+        [
+            branch
+            for branch in snapshot["branches"].keys()
+            if branch.startswith("refs/pull/")
+        ]
+    )
+    url = reverse(
+        "browse-origin-directory",
+        query_params={"origin_url": origin.url, "branch": pr_branch},
+    )
+    check_html_get_response(
+        client, url, status_code=200, template_used="browse/directory.html"
+    )