diff --git a/core/modules/file/file.routing.yml b/core/modules/file/file.routing.yml
index e182c97ee1..33f1acccf4 100644
--- a/core/modules/file/file.routing.yml
+++ b/core/modules/file/file.routing.yml
@@ -4,3 +4,15 @@ file.ajax_progress:
     _controller: '\Drupal\file\Controller\FileWidgetAjaxController::progress'
   requirements:
     _permission: 'access content'
+file.upload:
+  path: '/file/upload/{file}'
+  methods: [POST]
+  defaults:
+    _controller: '\Drupal\file\Controller\FileUploadController::upload'
+  requirements:
+    _access: 'TRUE'
+    #_permission: 'access content'
+  options:
+    parameters:
+      file:
+        type: entity:file
diff --git a/core/modules/file/src/Controller/FileUploadController.php b/core/modules/file/src/Controller/FileUploadController.php
new file mode 100644
index 0000000000..4d52906709
--- /dev/null
+++ b/core/modules/file/src/Controller/FileUploadController.php
@@ -0,0 +1,77 @@
+<?php
+
+namespace Drupal\file\Controller;
+
+use Drupal\Core\Controller\ControllerBase;
+use Drupal\Core\File\FileSystem;
+use Drupal\file\Entity\File;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\HttpKernel\Exception\HttpException;
+
+/**
+ * Handles binary file uploads.
+ */
+class FileUploadController extends ControllerBase {
+
+  /**
+   * @var \Drupal\Core\File\FileSystem
+   */
+  protected $fileSystem;
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container) {
+    return new static(
+      $container->get('file_system')
+    );
+  }
+
+  /**
+   * Constructs a FileUploadController instance.
+   *
+   * @param \Drupal\Core\File\FileSystem $file_system
+   */
+  public function __construct(FileSystem $file_system) {
+    $this->fileSystem = $file_system;
+  }
+
+  /**
+   * Handles binary file uploads.
+   *
+   * @param \Symfony\Component\HttpFoundation\Request $request
+   * @param \Drupal\file\Entity\File $file
+   */
+  public function upload(Request $request, File $file) {
+    if ($request->headers->get('Content-Type') !== 'application/octet-stream') {
+      throw new HttpException(400, '"application/octet-stream" must be used to POST binary file data');
+    }
+
+    // 'rb' is needed so reading works correctly on windows environments too.
+    $file_data = fopen('php://input','rb');
+
+    $temp_name = $this->fileSystem->tempnam('temporary://', 'file');
+
+    if ($temp = fopen($temp_name, 'wb')) {
+      while(!feof($file_data)) {
+        fwrite($temp, fread($file_data,4096));
+      }
+
+      fclose($temp);
+
+      // Move the file to the correct location based on the file entity,
+      // replacing any existing file.
+      file_unmanaged_move($temp_name, $file->getFileUri(), FILE_EXISTS_REPLACE);
+    }
+    else {
+      throw new HttpException(500, 'Temporary file could not be opened');
+    }
+
+    fclose($file_data);
+
+    return new Response('OK');
+  }
+
+}
