diff --git a/lib/internal/Magento/Framework/App/Http/Context.php b/lib/internal/Magento/Framework/App/Http/Context.php
index 4146dac725f03a70971e85d6a29b27803e795412..4d1f5e01d10de1188bfc1414bba0fcd045dc4be2 100644
--- a/lib/internal/Magento/Framework/App/Http/Context.php
+++ b/lib/internal/Magento/Framework/App/Http/Context.php
@@ -27,6 +27,16 @@ class Context
      */
     protected $default = [];
 
+    /**
+     * @param array $data
+     * @param array $default
+     */
+    public function __construct(array $data = [], array $default = [])
+    {
+        $this->data = $data;
+        $this->default = $default;
+    }
+
     /**
      * Data setter
      *
@@ -99,4 +109,17 @@ class Context
         }
         return null;
     }
+
+    /**
+     * Get data and default data in "key-value" format
+     *
+     * @return array
+     */
+    public function toArray()
+    {
+        return [
+            'data' => $this->data,
+            'default' => $this->default
+        ];
+    }
 }
diff --git a/lib/internal/Magento/Framework/App/PageCache/Kernel.php b/lib/internal/Magento/Framework/App/PageCache/Kernel.php
index 8a83592bc322e86c046b68480f815878f3de8855..fc2521ac747780350c8c33114ea8ba399eaa723f 100644
--- a/lib/internal/Magento/Framework/App/PageCache/Kernel.php
+++ b/lib/internal/Magento/Framework/App/PageCache/Kernel.php
@@ -5,8 +5,6 @@
  */
 namespace Magento\Framework\App\PageCache;
 
-use Magento\Framework\App\ObjectManager;
-
 /**
  * Builtin cache processor
  */
@@ -34,19 +32,76 @@ class Kernel
      */
     private $fullPageCache;
 
+    /**
+     * @var \Magento\Framework\Serialize\SerializerInterface
+     */
+    private $serializer;
+
+    /**
+     * @var \Magento\Framework\App\Http\Context
+     */
+    private $context;
+
+    /**
+     * @var \Magento\Framework\App\Http\ContextFactory
+     */
+    private $contextFactory;
+
+    /**
+     * @var \Magento\Framework\App\Response\HttpFactory
+     */
+    private $httpFactory;
+
     /**
      * @param Cache $cache
      * @param Identifier $identifier
      * @param \Magento\Framework\App\Request\Http $request
+     * @param \Magento\Framework\App\Http\Context|null $context
+     * @param \Magento\Framework\App\Http\ContextFactory|null $contextFactory
+     * @param \Magento\Framework\App\Response\HttpFactory|null $httpFactory
+     * @param \Magento\Framework\Serialize\SerializerInterface|null $serializer
      */
     public function __construct(
         \Magento\Framework\App\PageCache\Cache $cache,
         \Magento\Framework\App\PageCache\Identifier $identifier,
-        \Magento\Framework\App\Request\Http $request
+        \Magento\Framework\App\Request\Http $request,
+        \Magento\Framework\App\Http\Context $context = null,
+        \Magento\Framework\App\Http\ContextFactory $contextFactory = null,
+        \Magento\Framework\App\Response\HttpFactory $httpFactory = null,
+        \Magento\Framework\Serialize\SerializerInterface $serializer = null
     ) {
         $this->cache = $cache;
         $this->identifier = $identifier;
         $this->request = $request;
+
+        if ($context) {
+            $this->context = $context;
+        } else {
+            $this->context = \Magento\Framework\App\ObjectManager::getInstance()->get(
+                \Magento\Framework\App\Http\Context::class
+            );
+        }
+        if ($contextFactory) {
+            $this->contextFactory = $contextFactory;
+        } else {
+            $this->contextFactory = \Magento\Framework\App\ObjectManager::getInstance()->get(
+                \Magento\Framework\App\Http\ContextFactory::class
+            );
+        }
+        if ($httpFactory) {
+            $this->httpFactory = $httpFactory;
+        } else {
+            $this->httpFactory = \Magento\Framework\App\ObjectManager::getInstance()->get(
+                \Magento\Framework\App\Response\HttpFactory::class
+            );
+        }
+        if ($serializer) {
+            $this->serializer = $serializer;
+        } else {
+            $this->serializer = \Magento\Framework\App\ObjectManager::getInstance()->get(
+                \Magento\Framework\Serialize\SerializerInterface::class
+            );
+        }
     }
 
     /**
@@ -57,7 +112,12 @@ class Kernel
     public function load()
     {
         if ($this->request->isGet() || $this->request->isHead()) {
-            return unserialize($this->getCache()->load($this->identifier->getValue()));
+            $responseData = $this->serializer->unserialize($this->getCache()->load($this->identifier->getValue()));
+            if (!$responseData) {
+                return false;
+            }
+
+            return $this->buildResponse($responseData);
         }
         return false;
     }
@@ -84,11 +144,63 @@ class Kernel
                 if (!headers_sent()) {
                     header_remove('Set-Cookie');
                 }
-                $this->getCache()->save(serialize($response), $this->identifier->getValue(), $tags, $maxAge);
+
+                $this->getCache()->save(
+                    $this->serializer->serialize($this->getPreparedData($response)),
+                    $this->identifier->getValue(),
+                    $tags,
+                    $maxAge
+                );
             }
         }
     }
 
+    /**
+     * Get prepared data for storage in the cache.
+     *
+     * @param \Magento\Framework\App\Response\Http $response
+     * @return array
+     */
+    private function getPreparedData(\Magento\Framework\App\Response\Http $response)
+    {
+        return [
+            'content' => $response->getContent(),
+            'status_code' => $response->getStatusCode(),
+            'headers' => $response->getHeaders()->toArray(),
+            'context' => $this->context->toArray()
+        ];
+
+    }
+
+    /**
+     * Build response using response data.
+     *
+     * @param array $responseData
+     * @return \Magento\Framework\App\Response\Http
+     */
+    private function buildResponse($responseData)
+    {
+        $context = $this->contextFactory->create(
+            [
+                'data' => $responseData['context']['data'],
+                'default' => $responseData['context']['default']
+            ]
+        );
+
+        $response = $this->httpFactory->create(
+            [
+                'context' => $context
+            ]
+        );
+        $response->setStatusCode($responseData['status_code']);
+        $response->setContent($responseData['content']);
+        foreach ($responseData['headers'] as $headerKey => $headerValue) {
+            $response->setHeader($headerKey, $headerValue, true);
+        }
+
+        return $response;
+    }
+
     /**
      * TODO: Workaround to support backwards compatibility, will rework to use Dependency Injection in MAGETWO-49547
      *
@@ -97,7 +209,9 @@ class Kernel
     private function getCache()
     {
         if (!$this->fullPageCache) {
-            $this->fullPageCache = ObjectManager::getInstance()->get(\Magento\PageCache\Model\Cache\Type::class);
+            $this->fullPageCache = \Magento\Framework\App\ObjectManager::getInstance()->get(
+                \Magento\PageCache\Model\Cache\Type::class
+            );
         }
         return $this->fullPageCache;
     }
diff --git a/lib/internal/Magento/Framework/App/Test/Unit/Http/ContextTest.php b/lib/internal/Magento/Framework/App/Test/Unit/Http/ContextTest.php
index 05f589e0dc61a9299f717aeab0905f8b205fdafe..2c6b3dda23776efeeea023e2348bb3b751c7908b 100644
--- a/lib/internal/Magento/Framework/App/Test/Unit/Http/ContextTest.php
+++ b/lib/internal/Magento/Framework/App/Test/Unit/Http/ContextTest.php
@@ -64,4 +64,19 @@ class ContextTest extends \PHPUnit_Framework_TestCase
         ksort($data);
         $this->assertEquals(sha1(serialize($data)), $this->object->getVaryString());
     }
+
+    public function testToArray()
+    {
+        $newObject = new \Magento\Framework\App\Http\Context(['key' => 'value']);
+
+        $newObject->setValue('key1', 'value1', 'default1');
+        $newObject->setValue('key2', 'value2', 'default2');
+        $this->assertEquals(
+            [
+                'data' => ['key' => 'value', 'key1' => 'value1', 'key2' => 'value2'],
+                'default' => ['key1' => 'default1', 'key2' => 'default2']
+            ],
+            $newObject->toArray()
+        );
+    }
 }
diff --git a/lib/internal/Magento/Framework/App/Test/Unit/PageCache/KernelTest.php b/lib/internal/Magento/Framework/App/Test/Unit/PageCache/KernelTest.php
index 81b828b3f938c45333a5ac8b096d8b23d013a81a..1a85b481e53c1a5dcddd1ce77212145beaabc134 100644
--- a/lib/internal/Magento/Framework/App/Test/Unit/PageCache/KernelTest.php
+++ b/lib/internal/Magento/Framework/App/Test/Unit/PageCache/KernelTest.php
@@ -6,7 +6,12 @@
 namespace Magento\Framework\App\Test\Unit\PageCache;
 
 use \Magento\Framework\App\PageCache\Kernel;
+use \Magento\Framework\App\Http\ContextFactory;
+use \Magento\Framework\App\Response\HttpFactory;
 
+/**
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ */
 class KernelTest extends \PHPUnit_Framework_TestCase
 {
     /** @var Kernel */
@@ -27,39 +32,136 @@ class KernelTest extends \PHPUnit_Framework_TestCase
     /** @var  \PHPUnit_Framework_MockObject_MockObject|\Magento\PageCache\Model\Cache\Type */
     private $fullPageCacheMock;
 
+    /** @var \Magento\Framework\App\Response\Http|\PHPUnit_Framework_MockObject_MockObject */
+    private $httpResponseMock;
+
+    /** @var ContextFactory|\PHPUnit_Framework_MockObject_MockObject */
+    private $contextFactoryMock;
+
+    /** @var HttpFactory|\PHPUnit_Framework_MockObject_MockObject */
+    private $httpFactoryMock;
+
+    /** @var \Magento\Framework\Serialize\SerializerInterface|\PHPUnit_Framework_MockObject_MockObject */
+    private $serializer;
+
+    /** @var \Magento\Framework\App\Http\Context|\PHPUnit_Framework_MockObject_MockObject */
+    private $contextMock;
+
     /**
      * Setup
      */
     protected function setUp()
     {
+        $headersMock = $this->getMock(\Zend\Http\Headers::class, [], [], '', false);
         $this->cacheMock = $this->getMock(\Magento\Framework\App\PageCache\Cache::class, [], [], '', false);
         $this->fullPageCacheMock = $this->getMock(\Magento\PageCache\Model\Cache\Type::class, [], [], '', false);
-        $this->identifierMock =
-            $this->getMock(\Magento\Framework\App\PageCache\Identifier::class, [], [], '', false);
+        $this->contextMock = $this->getMock(\Magento\Framework\App\Http\Context::class, [], [], '', false);
+        $this->httpResponseMock = $this->getMock(\Magento\Framework\App\Response\Http::class, [], [], '', false);
+        $this->identifierMock = $this->getMock(\Magento\Framework\App\PageCache\Identifier::class, [], [], '', false);
         $this->requestMock = $this->getMock(\Magento\Framework\App\Request\Http::class, [], [], '', false);
-        $this->kernel = new Kernel($this->cacheMock, $this->identifierMock, $this->requestMock);
+        $this->serializer = $this->getMock(\Magento\Framework\Serialize\SerializerInterface::class, [], [], '', false);
+        $this->responseMock = $this->getMock(\Magento\Framework\App\Response\Http::class, [], [], '', false);
+        $this->contextFactoryMock = $this->getMock(ContextFactory::class, ['create'], [], '', false);
+        $this->httpFactoryMock = $this->getMock(HttpFactory::class, ['create'], [], '', false);
+        $this->responseMock->expects($this->any())->method('getHeaders')->willReturn($headersMock);
+
+        $this->kernel = new Kernel(
+            $this->cacheMock,
+            $this->identifierMock,
+            $this->requestMock,
+            $this->contextMock,
+            $this->contextFactoryMock,
+            $this->httpFactoryMock,
+            $this->serializer
+        );
 
         $reflection = new \ReflectionClass(\Magento\Framework\App\PageCache\Kernel::class);
         $reflectionProperty = $reflection->getProperty('fullPageCache');
         $reflectionProperty->setAccessible(true);
         $reflectionProperty->setValue($this->kernel, $this->fullPageCacheMock);
+    }
 
-        $this->responseMock = $this->getMockBuilder(
-            \Magento\Framework\App\Response\Http::class
-        )->setMethods(
-            ['getHeader', 'getHttpResponseCode', 'setNoCacheHeaders', 'clearHeader', '__wakeup']
-        )->disableOriginalConstructor()->getMock();
+    /**
+     * @dataProvider dataProviderForResultWithCachedData
+     * @param string $id
+     * @param mixed $cache
+     * @param bool $isGet
+     * @param bool $isHead
+     */
+    public function testLoadWithCachedData($id, $cache, $isGet, $isHead)
+    {
+        $this->serializer->expects($this->once())
+            ->method('unserialize')
+            ->willReturnCallback(
+                function ($value) {
+                    return json_decode($value, true);
+                }
+            );
+
+        $this->contextFactoryMock
+            ->expects($this->once())
+            ->method('create')
+            ->with(
+                [
+                    'data' => ['context_data'],
+                    'default' => ['context_default_data']
+                ]
+            )
+            ->willReturn($this->contextMock);
+
+        $this->httpFactoryMock
+            ->expects($this->once())
+            ->method('create')
+            ->with(['context' => $this->contextMock])
+            ->willReturn($this->httpResponseMock);
+
+        $this->requestMock->expects($this->once())->method('isGet')->will($this->returnValue($isGet));
+        $this->requestMock->expects($this->any())->method('isHead')->will($this->returnValue($isHead));
+        $this->fullPageCacheMock->expects(
+            $this->any()
+        )->method(
+            'load'
+        )->with(
+            $this->equalTo($id)
+        )->will(
+            $this->returnValue(json_encode($cache))
+        );
+        $this->httpResponseMock->expects($this->once())->method('setStatusCode')->with($cache['status_code']);
+        $this->httpResponseMock->expects($this->once())->method('setContent')->with($cache['content']);
+        $this->httpResponseMock->expects($this->once())->method('setHeader')->with(0, 'header', true);
+        $this->identifierMock->expects($this->any())->method('getValue')->will($this->returnValue($id));
+        $this->assertEquals($this->httpResponseMock, $this->kernel->load());
+    }
+
+    /**
+     * @return array
+     */
+    public function dataProviderForResultWithCachedData()
+    {
+        $data = [
+            'context' => [
+                'data' => ['context_data'],
+                'default' => ['context_default_data']
+            ],
+            'status_code' => 'status_code',
+            'content' => 'content',
+            'headers' => ['header']
+        ];
+
+        return [
+            ['existing key', $data, true, false],
+            ['existing key', $data, false, true],
+        ];
     }
 
     /**
-     * @dataProvider loadProvider
-     * @param mixed $expected
+     * @dataProvider dataProviderForResultWithoutCachedData
      * @param string $id
      * @param mixed $cache
      * @param bool $isGet
      * @param bool $isHead
      */
-    public function testLoad($expected, $id, $cache, $isGet, $isHead)
+    public function testLoadWithoutCachedData($id, $cache, $isGet, $isHead)
     {
         $this->requestMock->expects($this->once())->method('isGet')->will($this->returnValue($isGet));
         $this->requestMock->expects($this->any())->method('isHead')->will($this->returnValue($isHead));
@@ -70,31 +172,21 @@ class KernelTest extends \PHPUnit_Framework_TestCase
         )->with(
             $this->equalTo($id)
         )->will(
-            $this->returnValue(serialize($cache))
+            $this->returnValue(json_encode($cache))
         );
         $this->identifierMock->expects($this->any())->method('getValue')->will($this->returnValue($id));
-        $this->assertEquals($expected, $this->kernel->load());
+        $this->assertEquals(false, $this->kernel->load());
     }
 
     /**
      * @return array
      */
-    public function loadProvider()
+    public function dataProviderForResultWithoutCachedData()
     {
-        $data = [1, 2, 3];
         return [
-            [$data, 'existing key', $data, true, false],
-            [$data, 'existing key', $data, false, true],
-            [
-                new \Magento\Framework\DataObject($data),
-                'existing key',
-                new \Magento\Framework\DataObject($data),
-                true,
-                false
-            ],
-            [false, 'existing key', $data, false, false],
-            [false, 'non existing key', false, true, false],
-            [false, 'non existing key', false, false, false]
+            ['existing key', [], false, false],
+            ['non existing key', false, true, false],
+            ['non existing key', false, false, false]
         ];
     }
 
@@ -104,6 +196,14 @@ class KernelTest extends \PHPUnit_Framework_TestCase
      */
     public function testProcessSaveCache($httpCode, $at)
     {
+        $this->serializer->expects($this->once())
+            ->method('serialize')
+            ->willReturnCallback(
+                function ($value) {
+                    return json_encode($value);
+                }
+            );
+
         $cacheControlHeader = \Zend\Http\Header\CacheControl::fromString(
             'Cache-Control: public, max-age=100, s-maxage=100'
         );