diff --git a/src/wp-includes/rest-api.php b/src/wp-includes/rest-api.php
index a2e3363951..a4373a2d82 100644
--- a/src/wp-includes/rest-api.php
+++ b/src/wp-includes/rest-api.php
@@ -602,8 +602,9 @@ function rest_send_cors_headers( $value ) {
  * @since 4.4.0
  *
  * @param mixed           $response Current response, either response or `null` to indicate pass-through.
- * @param WP_REST_Server  $handler  ResponseHandler instance (usually WP_REST_Server).
- * @param WP_REST_Request $request  The request that was used to make current response.
+ * @param WP_REST_Server  $handler ResponseHandler instance (usually WP_REST_Server).
+ * @param WP_REST_Request $request The request that was used to make current response.
+ *
  * @return WP_REST_Response Modified response, either response or `null` to indicate pass-through.
  */
 function rest_handle_options_request( $response, $handler, $request ) {
@@ -615,18 +616,36 @@ function rest_handle_options_request( $response, $handler, $request ) {
 	$data     = array();
 
 	foreach ( $handler->get_routes() as $route => $endpoints ) {
-		$match = preg_match( '@^' . $route . '$@i', $request->get_route() );
+		$match = preg_match( '@^' . $route . '$@i', $request->get_route(), $matches );
 
 		if ( ! $match ) {
 			continue;
 		}
 
+		$args = array();
+		foreach ( $matches as $param => $value ) {
+			if ( ! is_int( $param ) ) {
+				$args[ $param ] = $value;
+			}
+		}
+
+		foreach ( $endpoints as $endpoint ) {
+			// Remove the redundant preg_match argument.
+			unset( $args[0] );
+
+			$request->set_url_params( $args );
+			$request->set_attributes( $endpoint );
+		}
+
 		$data = $handler->get_data_for_route( $route, $endpoints, 'help' );
 		$response->set_matched_route( $route );
 		break;
 	}
 
+	$response = rest_send_allow_header( $response, $handler, $request );
+
 	$response->set_data( $data );
+
 	return $response;
 }
 
diff --git a/tests/phpunit/tests/rest-api/rest-posts-controller.php b/tests/phpunit/tests/rest-api/rest-posts-controller.php
index ee01eb717e..f718c0d9e3 100644
--- a/tests/phpunit/tests/rest-api/rest-posts-controller.php
+++ b/tests/phpunit/tests/rest-api/rest-posts-controller.php
@@ -189,6 +189,14 @@ class WP_Test_REST_Posts_Controller extends WP_Test_REST_Post_Type_Controller_Te
 		$this->assertEquals( array( 'context', 'id', 'password' ), $keys );
 	}
 
+	public function test_allow_method_options() {
+		$request  = new WP_REST_Request( 'OPTIONS', sprintf( '/wp/v2/posts/%d', self::$post_id ) );
+		$response = rest_get_server()->dispatch( $request );
+		$headers  = $response->get_headers();
+
+		$this->assertNotEmpty( $headers['Allow'] );
+	}
+
 	public function test_get_items() {
 		$request  = new WP_REST_Request( 'GET', '/wp/v2/posts' );
 		$response = rest_get_server()->dispatch( $request );
