diff --git src/wp-includes/default-filters.php src/wp-includes/default-filters.php
index 3402e48..2cee88f 100644
--- src/wp-includes/default-filters.php
+++ src/wp-includes/default-filters.php
@@ -300,6 +300,7 @@ add_action( 'post_updated',               'wp_save_post_revision',
 add_action( 'publish_post',               '_publish_post_hook',                       5, 1 );
 add_action( 'transition_post_status',     '_transition_post_status',                  5, 3 );
 add_action( 'transition_post_status',     '_update_term_count_on_transition_post_status', 10, 3 );
+add_action( 'transition_post_status',     '_update_post_parents',                    10, 3 );
 add_action( 'comment_form',               'wp_comment_form_unfiltered_html_nonce'          );
 add_action( 'wp_scheduled_delete',        'wp_scheduled_delete'                            );
 add_action( 'wp_scheduled_auto_draft_delete', 'wp_delete_auto_drafts'                      );
diff --git src/wp-includes/post.php src/wp-includes/post.php
index c02108e..dae7dec 100644
--- src/wp-includes/post.php
+++ src/wp-includes/post.php
@@ -6073,3 +6073,92 @@ function wp_add_trashed_suffix_to_post_name_for_post( $post ) {
 	clean_post_cache( $post->ID );
 	return $post_name;
 }
+
+/**
+ * Removes the post's parent post in case the parent gets trashed.
+ *
+ * Stores the old value in post meta so that it can be re-added if the
+ * parent post is untrashed.
+ *
+ * @since 4.7.0
+ * @access private
+ *
+ * @global wpdb $wpdb WordPress database abstraction object.
+ *
+ * @param WP_Post $post Post object.
+ */
+function wp_remove_post_parent( $post ) {
+	global $wpdb;
+
+	$post = get_post( $post );
+
+	$previous_parent = $post->post_parent;
+
+	update_post_meta( $post->ID, '_wp_old_post_parent', $previous_parent );
+	$wpdb->update( $wpdb->posts, array( 'post_parent' => 0 ), array( 'ID' => $post->ID ) );
+	clean_post_cache( $post->ID );
+
+	do_action( 'wp_remove_post_parent', $post, $previous_parent );
+}
+
+/**
+ * Restores a posts' parent post in case the parent is untrashed.
+ *
+ * @since 4.7.0
+ * @access private
+ *
+ * @global wpdb $wpdb WordPress database abstraction object.
+ *
+ * @param WP_Post $post Post object.
+ */
+function wp_restore_post_parent( $post ) {
+	global $wpdb;
+
+	$post = get_post( $post );
+
+	$previous_parent = $post->post_parent;
+	$old_post_parent = (int) get_post_meta( $post->ID, '_wp_old_post_parent', true );
+
+	delete_post_meta( $post->ID, '_wp_old_post_parent' );
+
+	if ( 0 === $old_post_parent || 0 !== $previous_parent || ! get_post( $old_post_parent ) ) {
+		return;
+	}
+
+	$wpdb->update( $wpdb->posts, array( 'post_parent' => $post->post_parent ), array( 'ID' => $post->ID ) );
+	clean_post_cache( $post->ID );
+
+	do_action( 'wp_restore_post_parent', $post, $previous_parent );
+}
+
+/**
+ *
+ * @param string  $new_status New post status.
+ * @param string  $old_status Old post status.
+ * @param WP_Post $post       Post object.
+ */
+function _update_post_parents( $new_status, $old_status, $post ) {
+	if ( ! is_post_type_hierarchical( $post->post_type ) ) {
+		return;
+	}
+
+	if ( 'publish' !== $old_status && 'publish' === $new_status ) {
+		$children = get_posts( array(
+			'fields'         => 'ids',
+			'meta_key'       => '_wp_old_post_parent',
+			'meta_value_num' => $post->ID,
+			'post_type'      => $post->post_type,
+		) );
+
+		array_map( 'wp_restore_post_parent', $children );
+	} else if ( 'publish' === $old_status && 'publish' !== $new_status ) {
+		$children = get_posts( array(
+			'fields'      => 'ids',
+			'post_parent' => $post->ID,
+			'post_status' => 'any',
+			'post_type'   => $post->post_type,
+		) );
+
+		array_map( 'wp_remove_post_parent', $children );
+	}
+}
