Index: src/wp-admin/admin-ajax.php
===================================================================
--- src/wp-admin/admin-ajax.php	(revision 31041)
+++ src/wp-admin/admin-ajax.php	(working copy)
@@ -61,7 +61,7 @@
 	'query-attachments', 'save-attachment', 'save-attachment-compat', 'send-link-to-editor',
 	'send-attachment-to-editor', 'save-attachment-order', 'heartbeat', 'get-revision-diffs',
 	'save-user-color-scheme', 'update-widget', 'query-themes', 'parse-embed', 'set-attachment-thumbnail',
-	'parse-media-shortcode', 'destroy-sessions'
+	'parse-media-shortcode', 'destroy-sessions', 'detach-from-parent'
 );
 
 // Register core Ajax calls.
Index: src/wp-admin/includes/ajax-actions.php
===================================================================
--- src/wp-admin/includes/ajax-actions.php	(revision 31041)
+++ src/wp-admin/includes/ajax-actions.php	(working copy)
@@ -2224,6 +2224,9 @@
 	if ( 'attachment' != $post['post_type'] )
 		wp_send_json_error();
 
+	if ( isset( $changes['parent'] ) )
+		$post['post_parent'] = $changes['parent'];
+
 	if ( isset( $changes['title'] ) )
 		$post['post_title'] = $changes['title'];
 
@@ -2805,3 +2808,21 @@
 
 	wp_send_json_success( array( 'message' => $message ) );
 }
+
+/**
+ * AJAX handler for detaching an attachment from its parent
+ *
+ * @since 4.2.0
+ */
+function wp_ajax_detach_from_parent() {
+	$post = get_post( (int) $_POST['id'] );
+	if ( ! $post || ! $post->post_parent || ! current_user_can( 'edit_post', $post->ID ) ) {
+		wp_send_json_error();
+	}
+
+	if ( ! wp_update_post( array( 'post_parent' => 0, 'ID' => $post->ID ) ) ) {
+		wp_send_json_error();
+	}
+
+	wp_send_json_success();
+}
Index: src/wp-admin/includes/class-wp-media-list-table.php
===================================================================
--- src/wp-admin/includes/class-wp-media-list-table.php	(revision 31042)
+++ src/wp-admin/includes/class-wp-media-list-table.php	(working copy)
@@ -411,7 +411,10 @@
 				} else {
 					echo $title;
 				} ?></strong>,
-				<?php echo get_the_time( __( 'Y/m/d' ) ); ?>
+				<?php echo get_the_time( __( 'Y/m/d' ) ); ?><br />
+				<?php if ( $user_can_edit ) { ?>
+					<a class="hide-if-no-js detach-from-parent" data-id="<?php echo $post->ID ?>" href="#the-list"><?php _e( 'Detach' ); ?></a>
+				<?php } ?>
 			</td>
 <?php
 		} else {
Index: src/wp-admin/js/media.js
===================================================================
--- src/wp-admin/js/media.js	(revision 31041)
+++ src/wp-admin/js/media.js	(working copy)
@@ -110,5 +110,29 @@
 		$( '.find-box-inside' ).on( 'click', 'tr', function() {
 			$( this ).find( '.found-radio input' ).prop( 'checked', true );
 		});
+
+		// Needs to work for list table rows and the grid details modal
+		$( '.wp-list-table' ).on( 'click', '.detach-from-parent', function (e) {
+			e.preventDefault();
+
+			var $el = $( e.currentTarget ), id, url;
+
+			id = $el.data( 'id' );
+
+			$.ajax({
+				url: ajaxurl,
+				type: 'post',
+				data: {
+					id: id,
+					action: 'detach-from-parent'
+				}
+			}).done( function () {
+				url = window.location.href.split('#')[0];
+				url = url.replace(/[\?&]detached-[0-9]+/, '');
+				url += url.indexOf( '?' ) > -1 ? '&' : '?';
+				url += 'detached-' + id;
+				window.location = url + '#post-' + id;
+			} );
+		} );
 	});
 })( jQuery );
Index: src/wp-includes/js/media-views.js
===================================================================
--- src/wp-includes/js/media-views.js	(revision 31041)
+++ src/wp-includes/js/media-views.js	(working copy)
@@ -5118,22 +5118,23 @@
 				} );
 
 			if ( options.rerenderOnModelChange ) {
-				this.model.on( 'change', this.render, this );
+				this.listenTo( this.model, 'change', this.render );
 			} else {
-				this.model.on( 'change:percent', this.progress, this );
+				this.listenTo( this.model, 'change:percent', this.progress );
+				this.listenTo( this.model, 'change:parent', this.render );
 			}
-			this.model.on( 'change:title', this._syncTitle, this );
-			this.model.on( 'change:caption', this._syncCaption, this );
-			this.model.on( 'change:artist', this._syncArtist, this );
-			this.model.on( 'change:album', this._syncAlbum, this );
+			this.listenTo( this.model, 'change:title', this._syncTitle );
+			this.listenTo( this.model, 'change:caption', this._syncCaption );
+			this.listenTo( this.model, 'change:artist', this._syncArtist );
+			this.listenTo( this.model, 'change:album', this._syncAlbum );
 
 			// Update the selection.
-			this.model.on( 'add', this.select, this );
-			this.model.on( 'remove', this.deselect, this );
+			this.listenTo( this.model, 'add', this.select );
+			this.listenTo( this.model, 'remove', this.deselect );
 			if ( selection ) {
 				selection.on( 'reset', this.updateSelect, this );
 				// Update the model's details view.
-				this.model.on( 'selection:single selection:unsingle', this.details, this );
+				this.listenTo( this.model, 'selection:single selection:unsingle', this.details );
 				this.details( this.model, this.controller.state().get('selection') );
 			}
 
@@ -7061,7 +7062,8 @@
 			'click .untrash-attachment':      'untrashAttachment',
 			'click .edit-attachment':         'editAttachment',
 			'click .refresh-attachment':      'refreshAttachment',
-			'keydown':                        'toggleSelectionHandler'
+			'keydown':                        'toggleSelectionHandler',
+			'click .detach-from-parent':      'detachFromParent'
 		},
 
 		initialize: function() {
@@ -7160,6 +7162,19 @@
 				this.controller.trigger( 'attachment:keydown:arrow', event );
 				return;
 			}
+		},
+		/**
+		 * @param {Object} event
+		 */
+		detachFromParent: function( event ) {
+			event.preventDefault();
+
+			this.model.save({
+				'parent' : 0,
+				'uploadedTo' : 0,
+				'uploadedToLink' : '',
+				'uploadedToTitle' : ''
+			});
 		}
 	});
 
Index: src/wp-includes/media-template.php
===================================================================
--- src/wp-includes/media-template.php	(revision 31041)
+++ src/wp-includes/media-template.php	(working copy)
@@ -418,6 +418,9 @@
 						<# } else { #>
 							<span class="value">{{ data.uploadedToTitle }}</span>
 						<# } #>
+						<# if ( data.nonces.edit ) { #>
+						<a class="detach-from-parent" data-id="{{ data.id }}" href="#">(<?php _e( 'Detach' ); ?>)</a>
+						<# } #>
 					</label>
 				<# } #>
 				<div class="attachment-compat"></div>
