diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product.php b/app/code/Magento/CatalogImportExport/Model/Import/Product.php
index 54208dcdba534139c96e8fd975e0757f9ecb11e1..ceb5580307c22e07486effd290c61e88f768c84a 100644
--- a/app/code/Magento/CatalogImportExport/Model/Import/Product.php
+++ b/app/code/Magento/CatalogImportExport/Model/Import/Product.php
@@ -1416,7 +1416,7 @@ class Product extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity
     }
 
     /**
-     * Get existing images for current bucnh
+     * Get existing images for current bunch
      *
      * @param array $bunch
      * @return array
@@ -1436,7 +1436,21 @@ class Product extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity
         )->joinInner(
             ['mgvte' => $this->mediaGalleryEntityToValueTableName],
             '(mg.value_id = mgvte.value_id)',
-            [$this->getProductEntityLinkField() => 'mgvte.' . $this->getProductEntityLinkField()]
+            [
+                $this->getProductEntityLinkField() => 'mgvte.' . $this->getProductEntityLinkField(),
+                'value_id' => 'mgvte.value_id'
+            ]
+        )->joinLeft(
+            ['mgv' => $this->mediaGalleryValueTableName],
+            sprintf(
+                '(mg.value_id = mgv.value_id AND mgv.%s = mgvte.%s AND mgv.store_id = %d)',
+                $this->getProductEntityLinkField(),
+                $this->getProductEntityLinkField(),
+                \Magento\Store\Model\Store::DEFAULT_STORE_ID
+            ),
+            [
+                'label' => 'mgv.label'
+            ]
         )->joinInner(
             ['pe' => $this->productEntityTableName],
             "(mgvte.{$this->getProductEntityLinkField()} = pe.{$this->getProductEntityLinkField()})",
@@ -1447,7 +1461,7 @@ class Product extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity
         );
 
         foreach ($this->_connection->fetchAll($select) as $image) {
-            $result[$image['sku']][$image['value']] = true;
+            $result[$image['sku']][$image['value']] = $image;
         }
 
         return $result;
@@ -1462,22 +1476,21 @@ class Product extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity
         $images = [];
         $labels = [];
         foreach ($this->_imagesArrayKeys as $column) {
-            $images[$column] = [];
-            $labels[$column] = [];
             if (!empty($rowData[$column])) {
                 $images[$column] = array_unique(
-                    explode($this->getMultipleValueSeparator(), $rowData[$column])
+                    array_map(
+                        'trim',
+                        explode($this->getMultipleValueSeparator(), $rowData[$column])
+                    )
                 );
-            }
 
-            if (!empty($rowData[$column . '_label'])) {
-                $labels[$column] = explode($this->getMultipleValueSeparator(), $rowData[$column . '_label']);
-            }
+                if (!empty($rowData[$column . '_label'])) {
+                    $labels[$column] = $this->parseMultipleValues($rowData[$column . '_label']);
 
-            if (count($labels[$column]) > count($images[$column])) {
-                $labels[$column] = array_slice($labels[$column], 0, count($images[$column]));
-            } elseif (count($labels[$column]) < count($images[$column])) {
-                $labels[$column] = array_pad($labels[$column], count($images[$column]), '');
+                    if (count($labels[$column]) > count($images[$column])) {
+                        $labels[$column] = array_slice($labels[$column], 0, count($images[$column]));
+                    }
+                }
             }
         }
 
@@ -1507,6 +1520,7 @@ class Product extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity
             $this->categoriesCache = [];
             $tierPrices = [];
             $mediaGallery = [];
+            $labelsForUpdate = [];
             $uploadedImages = [];
             $previousType = null;
             $prevAttributeSet = null;
@@ -1616,7 +1630,7 @@ class Product extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity
                 foreach ($rowImages as $column => $columnImages) {
                     foreach ($columnImages as $position => $columnImage) {
                         if (!isset($uploadedImages[$columnImage])) {
-                            $uploadedFile = $this->uploadMediaFiles(trim($columnImage), true);
+                            $uploadedFile = $this->uploadMediaFiles($columnImage, true);
                             if ($uploadedFile) {
                                 $uploadedImages[$columnImage] = $uploadedFile;
                             } else {
@@ -1636,20 +1650,28 @@ class Product extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity
                             $rowData[$column] = $uploadedFile;
                         }
 
-                        $imageNotAssigned = !isset($existingImages[$rowSku][$uploadedFile]);
-
-                        if ($uploadedFile && $imageNotAssigned) {
-                            if ($column == self::COL_MEDIA_IMAGE) {
-                                $rowData[$column][] = $uploadedFile;
+                        if ($uploadedFile && !isset($mediaGallery[$rowSku][$uploadedFile])) {
+                            if (isset($existingImages[$rowSku][$uploadedFile])) {
+                                if (isset($rowLabels[$column][$position])
+                                    && $rowLabels[$column][$position] != $existingImages[$rowSku][$uploadedFile]['label']
+                                ) {
+                                    $labelsForUpdate[] = [
+                                        'label' => $rowLabels[$column][$position],
+                                        'imageData' => $existingImages[$rowSku][$uploadedFile]
+                                    ];
+                                }
+                            } else {
+                                if ($column == self::COL_MEDIA_IMAGE) {
+                                    $rowData[$column][] = $uploadedFile;
+                                }
+                                $mediaGallery[$rowSku][$uploadedFile] = [
+                                    'attribute_id' => $this->getMediaGalleryAttributeId(),
+                                    'label' => isset($rowLabels[$column][$position]) ? $rowLabels[$column][$position] : '',
+                                    'position' => $position + 1,
+                                    'disabled' => isset($disabledImages[$columnImage]) ? '1' : '0',
+                                    'value' => $uploadedFile,
+                                ];
                             }
-                            $mediaGallery[$rowSku][] = [
-                                'attribute_id' => $this->getMediaGalleryAttributeId(),
-                                'label' => isset($rowLabels[$column][$position]) ? $rowLabels[$column][$position] : '',
-                                'position' => $position + 1,
-                                'disabled' => isset($disabledImages[$columnImage]) ? '1' : '0',
-                                'value' => $uploadedFile,
-                            ];
-                            $existingImages[$rowSku][$uploadedFile] = true;
                         }
                     }
                 }
@@ -1767,6 +1789,8 @@ class Product extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity
                 $mediaGallery
             )->_saveProductAttributes(
                 $attributes
+            )->updateMediaGalleryLabels(
+                $labelsForUpdate
             );
 
             $this->_eventManager->dispatch(
@@ -2535,12 +2559,13 @@ class Product extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity
      * Parse values of multiselect attributes depends on "Fields Enclosure" parameter
      *
      * @param string $values
+     * @param string $delimiter
      * @return array
      */
-    public function parseMultiselectValues($values)
+    public function parseMultiselectValues($values, $delimiter = self::PSEUDO_MULTI_LINE_SEPARATOR)
     {
         if (empty($this->_parameters[Import::FIELDS_ENCLOSURE])) {
-            return explode(self::PSEUDO_MULTI_LINE_SEPARATOR, $values);
+            return explode($delimiter, $values);
         }
         if (preg_match_all('~"((?:[^"]|"")*)"~', $values, $matches)) {
             return $values = array_map(function ($value) {
@@ -2752,4 +2777,64 @@ class Product extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity
         }
         return $this->productEntityIdentifierField;
     }
+
+    /**
+     * Update media gallery labels
+     *
+     * @param array $labels
+     * @return void
+     */
+    private function updateMediaGalleryLabels(array $labels)
+    {
+        if (empty($labels)) {
+            return;
+        }
+
+        $insertData = [];
+        foreach ($labels as $label) {
+            $imageData = $label['imageData'];
+
+            if ($imageData['label'] === null) {
+                $insertData[] = [
+                    'label' => $label['label'],
+                    $this->getProductEntityLinkField() => $imageData[$this->getProductEntityLinkField()],
+                    'value_id' => $imageData['value_id'],
+                    'store_id' => \Magento\Store\Model\Store::DEFAULT_STORE_ID
+                ];
+            } else {
+                $this->_connection->update(
+                    $this->mediaGalleryValueTableName,
+                    [
+                        'label' => $label['label']
+                    ],
+                    [
+                        $this->getProductEntityLinkField() . ' = ?' => $imageData[$this->getProductEntityLinkField()],
+                        'value_id = ?' => $imageData['value_id'],
+                        'store_id = ?' => \Magento\Store\Model\Store::DEFAULT_STORE_ID
+                    ]
+                );
+            }
+        }
+
+        if (!empty($insertData)) {
+            $this->_connection->insertMultiple(
+                $this->mediaGalleryValueTableName,
+                $insertData
+            );
+        }
+    }
+
+    /**
+     * Parse values from multiple attributes fields
+     *
+     * @param string $labelRow
+     * @return array
+     */
+    private function parseMultipleValues($labelRow)
+    {
+        return $this->parseMultiselectValues(
+            $labelRow,
+            $this->getMultipleValueSeparator()
+        );
+    }
 }
diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product/Validator/Media.php b/app/code/Magento/CatalogImportExport/Model/Import/Product/Validator/Media.php
index 0b728ee5038873ddbb7a56eab967fcdf53c6c419..3067aa3c2b2eb29eb032201b0c6d062ab54baa08 100644
--- a/app/code/Magento/CatalogImportExport/Model/Import/Product/Validator/Media.php
+++ b/app/code/Magento/CatalogImportExport/Model/Import/Product/Validator/Media.php
@@ -5,7 +5,6 @@
  */
 namespace Magento\CatalogImportExport\Model\Import\Product\Validator;
 
-use Magento\CatalogImportExport\Model\Import\Product\Validator\AbstractImportValidator;
 use Magento\CatalogImportExport\Model\Import\Product\RowValidatorInterface;
 
 class Media extends AbstractImportValidator implements RowValidatorInterface
@@ -16,19 +15,15 @@ class Media extends AbstractImportValidator implements RowValidatorInterface
 
     const ADDITIONAL_IMAGES = 'additional_images';
 
+    /**
+     * @deprecated
+     * @see \Magento\CatalogImportExport\Model\Import\Product::getMultipleValueSeparator()
+     */
     const ADDITIONAL_IMAGES_DELIMITER = ',';
 
     /** @var array */
     protected $mediaAttributes = ['image', 'small_image', 'thumbnail'];
 
-    /**
-     * {@inheritdoc}
-     */
-    public function init($context)
-    {
-        return parent::init($context);
-    }
-
     /**
      * @param string $string
      * @return bool
@@ -83,7 +78,7 @@ class Media extends AbstractImportValidator implements RowValidatorInterface
             }
         }
         if (isset($value[self::ADDITIONAL_IMAGES]) && strlen($value[self::ADDITIONAL_IMAGES])) {
-            foreach (explode(self::ADDITIONAL_IMAGES_DELIMITER, $value[self::ADDITIONAL_IMAGES]) as $image) {
+            foreach (explode($this->context->getMultipleValueSeparator(), $value[self::ADDITIONAL_IMAGES]) as $image) {
                 if (!$this->checkPath($image) && !$this->checkValidUrl($image)) {
                     $this->_addMessages(
                         [
diff --git a/app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/Product/Validator/MediaTest.php b/app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/Product/Validator/MediaTest.php
index a4a937f25cf81334e19ef1aa079c1d274f79bacd..df7b33c72995b1a7a78faa6f0d5d74daf7ce8a5e 100644
--- a/app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/Product/Validator/MediaTest.php
+++ b/app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/Product/Validator/MediaTest.php
@@ -6,11 +6,14 @@
 
 namespace Magento\CatalogImportExport\Test\Unit\Model\Import\Product\Validator;
 
+use Magento\CatalogImportExport\Model\Import\Product;
+use Magento\CatalogImportExport\Model\Import\Product\Validator\Media;
 use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper;
+use Magento\ImportExport\Model\Import;
 
 class MediaTest extends \PHPUnit_Framework_TestCase
 {
-    /** @var \Magento\CatalogImportExport\Model\Import\Product\Validator\Media */
+    /** @var Media */
     protected $media;
 
     /** @var ObjectManagerHelper */
@@ -21,7 +24,7 @@ class MediaTest extends \PHPUnit_Framework_TestCase
         
         $this->objectManagerHelper = new ObjectManagerHelper($this);
         $this->media = $this->objectManagerHelper->getObject(
-            \Magento\CatalogImportExport\Model\Import\Product\Validator\Media::class,
+            Media::class,
             [
                 
             ]
@@ -41,6 +44,18 @@ class MediaTest extends \PHPUnit_Framework_TestCase
      */
     public function testIsValid($data, $expected)
     {
+        $contextMock = $this->getMockBuilder(Product::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $contextMock->expects($this->any())
+            ->method('getMultipleValueSeparator')
+            ->willReturn(Import::DEFAULT_GLOBAL_MULTI_VALUE_SEPARATOR);
+        $contextMock->expects($this->any())
+            ->method('retrieveMessageTemplate')
+            ->with(Media::ERROR_INVALID_MEDIA_URL_OR_PATH)
+            ->willReturn('%s');
+        $this->media->init($contextMock);
+
         $result = $this->media->isValid($data);
         $this->assertEquals($expected['result'], $result);
         $messages = $this->media->getMessages();
@@ -50,7 +65,7 @@ class MediaTest extends \PHPUnit_Framework_TestCase
     public function testIsValidClearMessagesCall()
     {
         $media = $this->getMock(
-            \Magento\CatalogImportExport\Model\Import\Product\Validator\Media::class,
+            Media::class,
             ['_clearMessages'],
             [],
             '',
@@ -78,6 +93,14 @@ class MediaTest extends \PHPUnit_Framework_TestCase
             'invalid' => [
                 ['_media_image' => 1],
                 ['result' => true,'messages' => []],
+            ],
+            'additional_images' => [
+                ['additional_images' => 'image1.png,image2.jpg'],
+                ['result' => true, 'messages' => []]
+            ],
+            'additional_images_fail' => [
+                ['additional_images' => 'image1.png|image2.jpg|image3.gif'],
+                ['result' => false, 'messages' => [0 => 'additional_images']]
             ]
         ];
     }
diff --git a/app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/ProductTest.php b/app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/ProductTest.php
index bf9c694d949d44709be47b73f08dd4eeb2c50c18..cd1fedf82fe85a4b0ea0b55ff056c38cd5ee8e4c 100644
--- a/app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/ProductTest.php
+++ b/app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/ProductTest.php
@@ -1280,6 +1280,43 @@ class ProductTest extends \Magento\ImportExport\Test\Unit\Model\Import\AbstractI
         $importProduct->validateRow($rowData, $rowNum);
     }
 
+    /**
+     * @dataProvider getImagesFromRowDataProvider
+     */
+    public function testGetImagesFromRow($rowData, $expectedResult)
+    {
+        $this->assertEquals(
+            $this->importProduct->getImagesFromRow($rowData),
+            $expectedResult
+        );
+    }
+
+    public function getImagesFromRowDataProvider()
+    {
+        return [
+            [
+                [],
+                [[], []]
+            ],
+            [
+                [
+                    'image' => 'image3.jpg',
+                    '_media_image' => 'image1.jpg,image2.png',
+                    '_media_image_label' => 'label1,label2'
+                ],
+                [
+                    [
+                        'image' => ['image3.jpg'],
+                        '_media_image' => ['image1.jpg', 'image2.png']
+                    ],
+                    [
+                        '_media_image' => ['label1', 'label2']
+                    ],
+                ]
+            ]
+        ];
+    }
+
     public function validateRowValidateNewProductTypeAddRowErrorCallDataProvider()
     {
         return [
diff --git a/app/code/Magento/Cms/Setup/UpgradeData.php b/app/code/Magento/Cms/Setup/UpgradeData.php
index 41a28989439af2e9ae14fe270b603e7e8c254abb..6d22f782b25b130b0cca1174e5386e7fb92cd5a7 100644
--- a/app/code/Magento/Cms/Setup/UpgradeData.php
+++ b/app/code/Magento/Cms/Setup/UpgradeData.php
@@ -13,6 +13,9 @@ use Magento\Framework\Setup\UpgradeDataInterface;
 
 class UpgradeData implements UpgradeDataInterface
 {
+    /**
+     * @deprecated
+     */
     const PRIVACY_COOKIE_PAGE_ID = 4;
 
     /**
@@ -234,7 +237,10 @@ class UpgradeData implements UpgradeDataInterface
     </table>
 </div>
 EOD;
-            $privacyAndCookiePolicyPage = $this->createPage()->load(self::PRIVACY_COOKIE_PAGE_ID);
+            $privacyAndCookiePolicyPage = $this->createPage()->load(
+                'privacy-policy-cookie-restriction-mode',
+                'identifier'
+            );
             $privacyAndCookiePolicyPageId = $privacyAndCookiePolicyPage->getId();
             if ($privacyAndCookiePolicyPageId) {
                 $privacyAndCookiePolicyPage->setContent($newPageContent);
diff --git a/app/code/Magento/SampleData/Model/Dependency.php b/app/code/Magento/SampleData/Model/Dependency.php
index 09f0c16aac848cafa797441137c9bc62f90a37ce..2a1849364bd77e0c43d19876579b3e2e7129b7ac 100644
--- a/app/code/Magento/SampleData/Model/Dependency.php
+++ b/app/code/Magento/SampleData/Model/Dependency.php
@@ -88,6 +88,10 @@ class Dependency
         foreach ($this->componentRegistrar->getPaths(ComponentRegistrar::MODULE) as $moduleDir) {
             $file = $moduleDir . '/composer.json';
 
+            if (!file_exists($file) || !is_readable($file)) {
+                continue;
+            }
+
             /** @var Package $package */
             $package = $this->getModuleComposerPackage($file);
             $suggest = json_decode(json_encode($package->get('suggest')), true);
diff --git a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php
index d8b2189e9f0d267d24d86ea77c67e84b2e2f73c9..c0e45410952717c783686e05b75d54eabdc6a295 100644
--- a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php
+++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php
@@ -568,52 +568,9 @@ class ProductTest extends \Magento\TestFramework\Indexer\TestCase
      */
     public function testSaveMediaImage()
     {
-        $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
-        $filesystem = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()
-            ->create(\Magento\Framework\Filesystem::class);
-        $directory = $filesystem->getDirectoryWrite(DirectoryList::ROOT);
-
-        $source = $this->objectManager->create(
-            \Magento\ImportExport\Model\Import\Source\Csv::class,
-            [
-                'file' => __DIR__ . '/_files/import_media.csv',
-                'directory' => $directory
-            ]
-        );
-        $this->_model->setParameters(
-            [
-                'behavior' => \Magento\ImportExport\Model\Import::BEHAVIOR_APPEND,
-                'entity' => 'catalog_product',
-                'import_images_file_dir' => 'pub/media/import'
-            ]
-        );
-        $appParams = \Magento\TestFramework\Helper\Bootstrap::getInstance()
-            ->getBootstrap()
-            ->getApplication()
-            ->getInitParams()[Bootstrap::INIT_PARAM_FILESYSTEM_DIR_PATHS];
-        $uploader = $this->_model->getUploader();
+        $this->importDataForMediaTest('import_media.csv');
+        $product = $this->getProductBySku('simple_new');
 
-        $destDir = $directory->getRelativePath($appParams[DirectoryList::MEDIA][DirectoryList::PATH] . '/catalog/product');
-        $tmpDir = $directory->getRelativePath($appParams[DirectoryList::MEDIA][DirectoryList::PATH] . '/import');
-
-        $directory->create($destDir);
-        $this->assertTrue($uploader->setDestDir($destDir));
-        $this->assertTrue($uploader->setTmpDir($tmpDir));
-        $errors = $this->_model->setSource(
-            $source
-        )->validateData();
-
-        $this->assertTrue($errors->getErrorsCount() == 0);
-        $this->_model->importData();
-        $this->assertTrue($this->_model->getErrorAggregator()->getErrorsCount() == 0);
-
-        $resource = $objectManager->get(\Magento\Catalog\Model\ResourceModel\Product::class);
-        $productId = $resource->getIdBySku('simple_new');
-
-        $product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
-            \Magento\Catalog\Model\Product::class
-        );
-        $product->load($productId);
         $this->assertEquals('/m/a/magento_image.jpg', $product->getData('swatch_image'));
         $gallery = $product->getMediaGalleryImages();
         $this->assertInstanceOf(\Magento\Framework\Data\Collection::class, $gallery);
@@ -625,6 +582,25 @@ class ProductTest extends \Magento\TestFramework\Indexer\TestCase
         $this->assertEquals('Image Label', $item->getLabel());
     }
 
+    /**
+     * Test that image labels updates after import
+     *
+     * @magentoDataFixture mediaImportImageFixture
+     * @magentoDataFixture Magento/Catalog/_files/product_with_image.php
+     */
+    public function testUpdateImageLabel()
+    {
+        $this->importDataForMediaTest('import_media_update_label.csv');
+        $product = $this->getProductBySku('simple');
+
+        $gallery = $product->getMediaGalleryImages();
+        $items = $gallery->getItems();
+        $this->assertCount(1, $items);
+        $item = array_pop($items);
+        $this->assertInstanceOf(\Magento\Framework\DataObject::class, $item);
+        $this->assertEquals('Updated Image Label', $item->getLabel());
+    }
+
     /**
      * Copy a fixture image into media import directory
      */
@@ -1432,6 +1408,68 @@ class ProductTest extends \Magento\TestFramework\Indexer\TestCase
             $product2->getData('multiselect_attribute'));
     }
 
+    /**
+     * Import and check data from file
+     *
+     * @param string $fileName
+     */
+    private function importDataForMediaTest($fileName)
+    {
+        $filesystem = $this->objectManager->create(\Magento\Framework\Filesystem::class);
+        $directory = $filesystem->getDirectoryWrite(DirectoryList::ROOT);
+
+        $source = $this->objectManager->create(
+            \Magento\ImportExport\Model\Import\Source\Csv::class,
+            [
+                'file' => __DIR__ . '/_files/' . $fileName,
+                'directory' => $directory
+            ]
+        );
+        $this->_model->setParameters(
+            [
+                'behavior' => \Magento\ImportExport\Model\Import::BEHAVIOR_APPEND,
+                'entity' => 'catalog_product',
+                'import_images_file_dir' => 'pub/media/import'
+            ]
+        );
+        $appParams = \Magento\TestFramework\Helper\Bootstrap::getInstance()
+            ->getBootstrap()
+            ->getApplication()
+            ->getInitParams()[Bootstrap::INIT_PARAM_FILESYSTEM_DIR_PATHS];
+        $uploader = $this->_model->getUploader();
+
+        $mediaPath = $appParams[DirectoryList::MEDIA][DirectoryList::PATH];
+        $destDir = $directory->getRelativePath($mediaPath . '/catalog/product');
+        $tmpDir = $directory->getRelativePath($mediaPath . '/import');
+
+        $directory->create($destDir);
+        $this->assertTrue($uploader->setDestDir($destDir));
+        $this->assertTrue($uploader->setTmpDir($tmpDir));
+        $errors = $this->_model->setSource(
+            $source
+        )->validateData();
+        $this->assertTrue($errors->getErrorsCount() == 0);
+
+        $this->_model->importData();
+        $this->assertTrue($this->_model->getErrorAggregator()->getErrorsCount() == 0);
+    }
+
+    /**
+     * Load product by given product sku
+     *
+     * @param string $sku
+     * @return \Magento\Catalog\Model\Product
+     */
+    private function getProductBySku($sku)
+    {
+        $resource = $this->objectManager->get(\Magento\Catalog\Model\ResourceModel\Product::class);
+        $productId = $resource->getIdBySku($sku);
+        $product = $this->objectManager->create(\Magento\Catalog\Model\Product::class);
+        $product->load($productId);
+
+        return $product;
+    }
+
     /**
      * @param array $row
      * @param string|null $behavior
diff --git a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/import_media_update_label.csv b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/import_media_update_label.csv
new file mode 100644
index 0000000000000000000000000000000000000000..4e62e28af7ff3c55232e5636334cb6023cbf2604
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/import_media_update_label.csv
@@ -0,0 +1,2 @@
+sku,store_view_code,attribute_set_code,product_type,categories,product_websites,name,description,short_description,weight,product_online,tax_class_name,visibility,price,special_price,special_price_from_date,special_price_to_date,url_key,meta_title,meta_keywords,meta_description,base_image,base_image_label,small_image,small_image_label,thumbnail_image,thumbnail_image_label,swatch_image,swatch_image_label1,created_at,updated_at,new_from_date,new_to_date,display_product_options_in,map_price,msrp_price,map_enabled,gift_message_available,custom_design,custom_design_from,custom_design_to,custom_layout_update,page_layout,product_options_container,msrp_display_actual_price_type,country_of_manufacture,additional_attributes,qty,out_of_stock_qty,use_config_min_qty,is_qty_decimal,allow_backorders,use_config_backorders,min_cart_qty,use_config_min_sale_qty,max_cart_qty,use_config_max_sale_qty,is_in_stock,notify_on_stock_below,use_config_notify_stock_qty,manage_stock,use_config_manage_stock,use_config_qty_increments,qty_increments,use_config_enable_qty_inc,enable_qty_increments,is_decimal_divided,website_id,related_skus,crosssell_skus,upsell_skus,additional_images,additional_image_labels,hide_from_product_page,custom_options,bundle_price_type,bundle_sku_type,bundle_price_view,bundle_weight_type,bundle_values,associated_skus
+simple,,Default,simple,,base,New Product,,,,1,Taxable Goods,"Catalog, Search",10,,,,new-product,New Product,New Product,New Product ,magento_image.jpg,,magento_image.jpg,,magento_image.jpg,,magento_image.jpg,,10/20/15 07:05,10/20/15 07:05,,,Block after Info Column,,,,,,,,,,,,,"has_options=1,quantity_and_stock_status=In Stock,required_options=1",100,0,1,0,0,1,1,1,10000,1,1,1,1,1,0,1,1,0,0,0,1,,,,magento_image.jpg,Updated Image Label,,,,,,,,
diff --git a/dev/tests/integration/testsuite/Magento/SampleData/Model/DependencyTest.php b/dev/tests/integration/testsuite/Magento/SampleData/Model/DependencyTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..4ff9104cec879f48f48edc28f9f9860a599519d9
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/SampleData/Model/DependencyTest.php
@@ -0,0 +1,73 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\SampleData\Model;
+
+use Magento\Framework\Composer\ComposerInformation;
+use Magento\Framework\Component\ComponentRegistrar;
+use Magento\Framework\Filesystem;
+use Magento\Framework\Config\Composer\PackageFactory;
+
+class DependencyTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\SampleData\Model\Dependency
+     */
+    private $model;
+
+    /**
+     * @var ComposerInformation|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $composerInformationMock;
+
+    /**
+     * @var ComponentRegistrar|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $componentRegistrarMock;
+
+    protected function setUp()
+    {
+        $this->composerInformationMock = $this->getMockBuilder(ComposerInformation::class)
+            ->disableOriginalConstructor()
+            ->disableOriginalClone()
+            ->getMock();
+        $this->componentRegistrarMock = $this->getMockBuilder(ComponentRegistrar::class)
+            ->disableOriginalConstructor()
+            ->disableOriginalClone()
+            ->getMock();
+
+        $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+        $this->model = $objectManager->create(
+            \Magento\SampleData\Model\Dependency::class,
+            [
+                'composerInformation' => $this->composerInformationMock,
+                'filesystem' => $objectManager->get(Filesystem::class),
+                'packageFactory' => $objectManager->get(PackageFactory::class),
+                'componentRegistrar' => $this->componentRegistrarMock
+            ]
+        );
+    }
+
+    public function testGetSampleDataPackages()
+    {
+        $this->composerInformationMock->expects($this->once())
+            ->method('getSuggestedPackages')
+            ->willReturn([]);
+        $this->componentRegistrarMock->expects($this->once())
+            ->method('getPaths')
+            ->with(ComponentRegistrar::MODULE)
+            ->willReturn([
+                __DIR__ . '/../_files/Modules/FirstModule',
+                __DIR__ . '/../_files/Modules/SecondModule',
+                __DIR__ . '/../_files/Modules/ThirdModule',
+                __DIR__ . '/../_files/Modules/FourthModule'
+            ]);
+
+        $this->assertSame(
+            ['magento/module-first-sample-data' => '777.7.*'],
+            $this->model->getSampleDataPackages()
+        );
+    }
+}
diff --git a/dev/tests/integration/testsuite/Magento/SampleData/_files/Modules/FirstModule/composer.json b/dev/tests/integration/testsuite/Magento/SampleData/_files/Modules/FirstModule/composer.json
new file mode 100644
index 0000000000000000000000000000000000000000..d3f063976ea9180bc790e3597e771179f8f26563
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/SampleData/_files/Modules/FirstModule/composer.json
@@ -0,0 +1,9 @@
+{
+  "name": "magento/module-first",
+  "description": "N/A",
+  "suggest": {
+    "magento/module-first-sample-data": "Sample Data version:777.7.*"
+  },
+  "type": "magento2-module",
+  "version": "777.7.7"
+}
diff --git a/dev/tests/integration/testsuite/Magento/SampleData/_files/Modules/SecondModule/composer.json b/dev/tests/integration/testsuite/Magento/SampleData/_files/Modules/SecondModule/composer.json
new file mode 100644
index 0000000000000000000000000000000000000000..b9e027b7bb6f5625dee2d8a64c26a9be6056c36b
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/SampleData/_files/Modules/SecondModule/composer.json
@@ -0,0 +1,9 @@
+{
+  "name": "magento/module-second",
+  "description": "N/A",
+  "suggest": {
+    "magento/module-some-module": "Some Module:888.8.*"
+  },
+  "type": "magento2-module",
+  "version": "777.7.7"
+}
diff --git a/dev/tests/integration/testsuite/Magento/SampleData/_files/Modules/ThirdModule/composer.json b/dev/tests/integration/testsuite/Magento/SampleData/_files/Modules/ThirdModule/composer.json
new file mode 100644
index 0000000000000000000000000000000000000000..2a0d642e8e282ecb2cec8ccb755a1dd3284f5a48
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/SampleData/_files/Modules/ThirdModule/composer.json
@@ -0,0 +1,6 @@
+{
+  "name": "magento/module-second",
+  "description": "N/A",
+  "type": "magento2-module",
+  "version": "777.7.7"
+}
diff --git a/lib/internal/Magento/Framework/App/Http.php b/lib/internal/Magento/Framework/App/Http.php
index b98998c55a40155ea785a9680c9b2e02beb85da9..e3de37bfc01f937618ae53ca897f16dc0b7fb188 100644
--- a/lib/internal/Magento/Framework/App/Http.php
+++ b/lib/internal/Magento/Framework/App/Http.php
@@ -241,8 +241,7 @@ class Http implements \Magento\Framework\AppInterface
                 . "because the Magento setup directory cannot be accessed. \n"
                 . 'You can install Magento using either the command line or you must restore access '
                 . 'to the following directory: ' . $setupInfo->getDir($projectRoot) . "\n";
-            $newMessage .= 'If you are using the sample nginx configuration, please go to '
-                . $this->_request->getScheme(). '://' . $this->_request->getHttpHost() . $setupInfo->getUrl();
+
             throw new \Exception($newMessage, 0, $exception);
         }
     }
diff --git a/lib/internal/Magento/Framework/App/SetupInfo.php b/lib/internal/Magento/Framework/App/SetupInfo.php
index b52daaac333e8c7f978aea2bcd156a68782bd6f1..731ec97ee7dd2d5dae8c2a372f454f11cf5755a7 100644
--- a/lib/internal/Magento/Framework/App/SetupInfo.php
+++ b/lib/internal/Magento/Framework/App/SetupInfo.php
@@ -147,6 +147,14 @@ class SetupInfo
     {
         $setupDir = $this->getDir($this->projectRoot);
         $isSubDir = false !== strpos($setupDir . '/', $this->docRoot . '/');
+        // Setup is not accessible from pub folder
+        $setupDir = rtrim($setupDir, '/');
+        $lastOccurrence = strrpos($setupDir, '/pub/setup');
+
+        if (false !== $lastOccurrence) {
+            $setupDir = substr_replace($setupDir, '/setup', $lastOccurrence, strlen('/pub/setup'));
+        }
+
         return $isSubDir && realpath($setupDir);
     }
 
diff --git a/lib/internal/Magento/Framework/App/Test/Unit/SetupInfoTest.php b/lib/internal/Magento/Framework/App/Test/Unit/SetupInfoTest.php
index 99ca759490f14d66d47988c70e34bf5d4e021ea2..61f0a34d8a0d78ebfe4d685d5f6ce5d30d1a057a 100644
--- a/lib/internal/Magento/Framework/App/Test/Unit/SetupInfoTest.php
+++ b/lib/internal/Magento/Framework/App/Test/Unit/SetupInfoTest.php
@@ -193,6 +193,13 @@ class SetupInfoTest extends \PHPUnit_Framework_TestCase
                 ],
                 true
             ],
+            'root within doc root + pub, existent sub-directory' => [
+                [
+                    'DOCUMENT_ROOT' => __DIR__ . '/_files/pub/',
+                    'SCRIPT_FILENAME' => __DIR__ . '/_files/pub/index.php',
+                ],
+                true
+            ],
         ];
     }
 }
diff --git a/lib/internal/Magento/Framework/App/Test/Unit/_files/pub/index.php b/lib/internal/Magento/Framework/App/Test/Unit/_files/pub/index.php
new file mode 100644
index 0000000000000000000000000000000000000000..2a0cd37c68d37453c3e881693f25953bac966c1e
--- /dev/null
+++ b/lib/internal/Magento/Framework/App/Test/Unit/_files/pub/index.php
@@ -0,0 +1,5 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
diff --git a/lib/internal/Magento/Framework/App/Test/Unit/_files/setup/index.php b/lib/internal/Magento/Framework/App/Test/Unit/_files/setup/index.php
new file mode 100644
index 0000000000000000000000000000000000000000..2a0cd37c68d37453c3e881693f25953bac966c1e
--- /dev/null
+++ b/lib/internal/Magento/Framework/App/Test/Unit/_files/setup/index.php
@@ -0,0 +1,5 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
diff --git a/pub/media/.htaccess b/pub/media/.htaccess
index 865ebd31b528b8183593ee5e55894dedc53a46fd..0a3087c096319f5d9974d643d33317ee0a4c4af2 100644
--- a/pub/media/.htaccess
+++ b/pub/media/.htaccess
@@ -11,6 +11,10 @@ php_flag engine 0
 AddHandler cgi-script .php .pl .py .jsp .asp .htm .shtml .sh .cgi
 Options -ExecCGI
 
+<FilesMatch ".+\.(ph(p[3457]?|t|tml)|[aj]sp|p[ly]|sh|cgi|shtml?|html?)$">
+SetHandler default-handler
+</FilesMatch>
+
 <IfModule mod_rewrite.c>
 
 ############################################
diff --git a/setup/src/Magento/Setup/Console/Command/UpgradeCommand.php b/setup/src/Magento/Setup/Console/Command/UpgradeCommand.php
index bbd0a44254e89ce2e84d3bbe7e043ac80c76a435..ad2ad3d7b6969dcf241bd9f273ae4330d9fedcd2 100644
--- a/setup/src/Magento/Setup/Console/Command/UpgradeCommand.php
+++ b/setup/src/Magento/Setup/Console/Command/UpgradeCommand.php
@@ -71,7 +71,7 @@ class UpgradeCommand extends AbstractSetupCommand
         $installer->installSchema();
         $installer->installDataFixtures();
         if (!$keepGenerated) {
-            $output->writeln('<info>Please re-run Magento compile command</info>');
+            $output->writeln('<info>Please re-run Magento compile command. Use the command "setup:di:compile"</info>');
         }
 
         return \Magento\Framework\Console\Cli::RETURN_SUCCESS;
diff --git a/setup/src/Magento/Setup/Test/Unit/Console/Command/UpgradeCommandTest.php b/setup/src/Magento/Setup/Test/Unit/Console/Command/UpgradeCommandTest.php
index 6209df88bd5f06880fad8c645128af079d61b482..dcbdc876db607a010e543b76c62d5410a4ca0132 100644
--- a/setup/src/Magento/Setup/Test/Unit/Console/Command/UpgradeCommandTest.php
+++ b/setup/src/Magento/Setup/Test/Unit/Console/Command/UpgradeCommandTest.php
@@ -11,7 +11,12 @@ use Magento\Framework\Console\Cli;
 
 class UpgradeCommandTest extends \PHPUnit_Framework_TestCase
 {
-    public function testExecute()
+    /**
+     * @param array $options
+     * @param string $expectedString
+     * @dataProvider executeDataProvider
+     */
+    public function testExecute($options = [], $expectedString = '')
     {
         $installerFactory = $this->getMock(\Magento\Setup\Model\InstallerFactory::class, [], [], '', false);
         $installer = $this->getMock(\Magento\Setup\Model\Installer::class, [], [], '', false);
@@ -20,6 +25,25 @@ class UpgradeCommandTest extends \PHPUnit_Framework_TestCase
         $installer->expects($this->at(2))->method('installDataFixtures');
         $installerFactory->expects($this->once())->method('create')->willReturn($installer);
         $commandTester = new CommandTester(new UpgradeCommand($installerFactory));
-        $this->assertSame(Cli::RETURN_SUCCESS, $commandTester->execute([]));
+        $this->assertSame(Cli::RETURN_SUCCESS, $commandTester->execute($options));
+        $this->assertEquals($expectedString, $commandTester->getDisplay());
+    }
+
+    /**
+     * @return array
+     */
+    public function executeDataProvider()
+    {
+        return [
+            [
+                'options' => [],
+                'expectedString' => 'Please re-run Magento compile command. Use the command "setup:di:compile"'
+                    . PHP_EOL
+            ],
+            [
+                'options' => ['--keep-generated' => true],
+                'expectedString' => ''
+            ],
+        ];
     }
 }