diff --git a/docs/api-levels.rst b/docs/api-levels.rst
index 5a52b78b4..2fdc42dbd 100644
--- a/docs/api-levels.rst
+++ b/docs/api-levels.rst
@@ -60,6 +60,7 @@ The available methods are:
 * ``http_get()``
 * ``http_post()``
 * ``http_put()``
+* ``http_patch()``
 * ``http_delete()``
 * ``http_list()`` (a wrapper around ``http_get`` handling pagination, including with lazy generators)
 * ``http_head()`` (only returns the header dictionary)
diff --git a/gitlab/client.py b/gitlab/client.py
index 5e6c71af0..c3982f39d 100644
--- a/gitlab/client.py
+++ b/gitlab/client.py
@@ -1094,6 +1094,54 @@ def http_put(
                 error_message="Failed to parse the server message"
             ) from e
 
+    def http_patch(
+        self,
+        path: str,
+        *,
+        query_data: Optional[Dict[str, Any]] = None,
+        post_data: Optional[Union[Dict[str, Any], bytes]] = None,
+        raw: bool = False,
+        **kwargs: Any,
+    ) -> Union[Dict[str, Any], requests.Response]:
+        """Make a PATCH request to the Gitlab server.
+
+        Args:
+            path: Path or full URL to query ('/projects' or
+                        'http://whatever/v4/api/projecs')
+            query_data: Data to send as query parameters
+            post_data: Data to send in the body (will be converted to
+                              json by default)
+            raw: If True, do not convert post_data to json
+            **kwargs: Extra options to send to the server (e.g. sudo)
+
+        Returns:
+            The parsed json returned by the server.
+
+        Raises:
+            GitlabHttpError: When the return code is not 2xx
+            GitlabParsingError: If the json data could not be parsed
+        """
+        query_data = query_data or {}
+        post_data = post_data or {}
+
+        result = self.http_request(
+            "patch",
+            path,
+            query_data=query_data,
+            post_data=post_data,
+            raw=raw,
+            **kwargs,
+        )
+        try:
+            json_result = result.json()
+            if TYPE_CHECKING:
+                assert isinstance(json_result, dict)
+            return json_result
+        except Exception as e:
+            raise gitlab.exceptions.GitlabParsingError(
+                error_message="Failed to parse the server message"
+            ) from e
+
     def http_delete(self, path: str, **kwargs: Any) -> requests.Response:
         """Make a DELETE request to the Gitlab server.
 
diff --git a/pyproject.toml b/pyproject.toml
index 744113051..75b8c1de6 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -58,6 +58,7 @@ disable = [
     "too-many-instance-attributes",
     "too-many-lines",
     "too-many-locals",
+    "too-many-public-methods",
     "too-many-statements",
     "unsubscriptable-object",
 ]
diff --git a/tests/unit/test_gitlab_http_methods.py b/tests/unit/test_gitlab_http_methods.py
index 569df8149..d7e375af1 100644
--- a/tests/unit/test_gitlab_http_methods.py
+++ b/tests/unit/test_gitlab_http_methods.py
@@ -809,6 +809,56 @@ def test_put_request_invalid_data(gl):
     assert responses.assert_call_count(url, 1) is True
 
 
+@responses.activate
+def test_patch_request(gl):
+    url = "http://localhost/api/v4/projects"
+    responses.add(
+        method=responses.PATCH,
+        url=url,
+        json={"name": "project1"},
+        status=200,
+        match=helpers.MATCH_EMPTY_QUERY_PARAMS,
+    )
+
+    result = gl.http_patch("/projects")
+    assert isinstance(result, dict)
+    assert result["name"] == "project1"
+    assert responses.assert_call_count(url, 1) is True
+
+
+@responses.activate
+def test_patch_request_404(gl):
+    url = "http://localhost/api/v4/not_there"
+    responses.add(
+        method=responses.PATCH,
+        url=url,
+        json=[],
+        status=404,
+        match=helpers.MATCH_EMPTY_QUERY_PARAMS,
+    )
+
+    with pytest.raises(GitlabHttpError):
+        gl.http_patch("/not_there")
+    assert responses.assert_call_count(url, 1) is True
+
+
+@responses.activate
+def test_patch_request_invalid_data(gl):
+    url = "http://localhost/api/v4/projects"
+    responses.add(
+        method=responses.PATCH,
+        url=url,
+        body='["name": "project1"]',
+        content_type="application/json",
+        status=200,
+        match=helpers.MATCH_EMPTY_QUERY_PARAMS,
+    )
+
+    with pytest.raises(GitlabParsingError):
+        gl.http_patch("/projects")
+    assert responses.assert_call_count(url, 1) is True
+
+
 @responses.activate
 def test_delete_request(gl):
     url = "http://localhost/api/v4/projects"