diff --git a/src/wp-admin/includes/dashboard.php b/src/wp-admin/includes/dashboard.php
index 919af94c0b..cd932a154f 100644
--- a/src/wp-admin/includes/dashboard.php
+++ b/src/wp-admin/includes/dashboard.php
@@ -79,6 +79,11 @@ function wp_dashboard_setup() {
 	// WordPress Events and News.
 	wp_add_dashboard_widget( 'dashboard_primary', __( 'WordPress Events and News' ), 'wp_dashboard_events_news' );
 
+	// Privacy.
+	if ( current_user_can( 'manage_privacy_options' ) || current_user_can( 'export_others_personal_data' ) || current_user_can( 'erase_others_personal_data' ) ) {
+		wp_add_dashboard_widget( 'dashboard_privacy', __( 'Privacy' ), 'wp_dashboard_privacy' );
+	}
+
 	if ( is_network_admin() ) {
 
 		/**
@@ -1849,6 +1854,144 @@ function wp_dashboard_site_health() {
 	<?php
 }
 
+/**
+ * Displays the Privacy widget.
+ *
+ * @since 5.4.0
+ */
+function wp_dashboard_privacy() {
+	// Show the policy message only to users with manage_privacy_options cap.
+	if ( current_user_can( 'manage_privacy_options' ) ) {
+		echo '<p>';
+
+		printf(
+			/* translators: 1: Privacy Policy guide URL*/
+			__( 'Need help putting together your Privacy Policy page? <a href="%1$s">Check out our guide</a> for recommendations on what content to include, along with policies suggested by your plugins and theme.' ),
+			esc_url( admin_url( 'privacy-policy-guide.php' ) )
+		);
+
+		echo '</p>';
+	}
+
+	// Show the export personal data stats only to users with export_others_personal_data cap.
+	if ( current_user_can( 'export_others_personal_data' ) ) {
+		$pending   = 0;
+		$confirmed = 0;
+		$failed    = 0;
+		$completed = 0;
+
+		$requests = get_posts(
+			array(
+				'numberposts'   => -1,
+				'post_type'     => 'user_request',
+				'post_name__in' => array( 'export_personal_data' ),  // Request type stored in post_name column.
+				'post_status'   => array(
+					'request-pending',
+					'request-confirmed',
+					'request-failed',
+					'request-completed',
+				),
+			)
+		);
+
+		foreach ( $requests as $request ) {
+			switch ( $request->post_status ) {
+				case 'request-pending':
+					$pending++;
+					break;
+				case 'request-confirmed':
+					$confirmed++;
+					break;
+				case 'request-failed':
+					$failed++;
+					break;
+				case 'request-completed':
+					$completed++;
+					break;
+			}
+		}
+		echo '<p>';
+		/* translators: %s: Number of Data Export Requests. */
+		$text = _n( '%s Export Personal Data Request', '%s Export Personal Data Requests', count( $requests ) );
+		$text = sprintf( $text, number_format_i18n( count( $requests ) ) );
+		/* translators: %1$s: Data Export Requests wp-admin screen. %2$s Number of Total Data Export Requests. */
+		printf(
+			'<a href="%1$s">%2$s</a>',
+			esc_url( admin_url( 'export-personal-data.php' ) ),
+			$text
+		);
+		echo '<br> &bull; ';
+		/* translators: %1$d Number of Pending Export Requests. */
+		echo sprintf( '%1$d Pending', $pending ) . ', ';
+		/* translators: %1$d Number of Confirmed Export Requests. */
+		echo sprintf( '%1$d Confirmed', $confirmed ) . ', ';
+		/* translators: %1$d Number of Failed Export Requests. */
+		echo sprintf( '%1$d Failed', $failed ) . ', ';
+		/* translators: %1$d Number of Completed Export Requests. */
+		echo sprintf( '%1$d Completed', $completed );
+		echo '</p>';
+	}
+
+	// Show the erase personal data stats only to users with erase_others_personal_data cap.
+	if ( current_user_can( 'erase_others_personal_data' ) ) {
+		$pending   = 0;
+		$confirmed = 0;
+		$failed    = 0;
+		$completed = 0;
+
+		$requests = get_posts(
+			array(
+				'numberposts'   => -1,
+				'post_type'     => 'user_request',
+				'post_name__in' => array( 'remove_personal_data' ),  // Request type stored in post_name column.
+				'post_status'   => array(
+					'request-pending',
+					'request-confirmed',
+					'request-failed',
+					'request-completed',
+				),
+			)
+		);
+
+		foreach ( $requests as $request ) {
+			switch ( $request->post_status ) {
+				case 'request-pending':
+					$pending++;
+					break;
+				case 'request-confirmed':
+					$confirmed++;
+					break;
+				case 'request-failed':
+					$failed++;
+					break;
+				case 'request-completed':
+					$completed++;
+					break;
+			}
+		}
+		echo '<p>';
+		/* translators: %s: Number of Data Export Requests. */
+		$text = _n( '%s Erase Personal Data Request', '%s Erase Personal Data Requests', count( $requests ) );
+		$text = sprintf( $text, number_format_i18n( count( $requests ) ) );
+		/* translators: %1$s: Data Export Requests wp-admin screen. %2$s Number of Total Data Export Requests. */
+		printf(
+			'<a href="%1$s">%2$s</a>',
+			esc_url( admin_url( 'erase-personal-data.php' ) ),
+			$text
+		);
+		echo '<br> &bull; ';
+		/* translators: %1$d Number of Pending Export Requests. */
+		echo sprintf( '%1$d Pending', $pending ) . ', ';
+		/* translators: %1$d Number of Confirmed Export Requests. */
+		echo sprintf( '%1$d Confirmed', $confirmed ) . ', ';
+		/* translators: %1$d Number of Failed Export Requests. */
+		echo sprintf( '%1$d Failed', $failed ) . ', ';
+		/* translators: %1$d Number of Completed Export Requests. */
+		echo sprintf( '%1$d Completed', $completed );
+		echo '</p>';
+	}
+}
+
 /**
  * Empty function usable by plugins to output empty dashboard widget (to be populated later by JS).
  *
