diff --git a/src/Microsoft.DotNet.ProjectModel/Compilation/LibraryAsset.cs b/src/Microsoft.DotNet.ProjectModel/Compilation/LibraryAsset.cs
index 69c203e84..d7740a94d 100644
--- a/src/Microsoft.DotNet.ProjectModel/Compilation/LibraryAsset.cs
+++ b/src/Microsoft.DotNet.ProjectModel/Compilation/LibraryAsset.cs
@@ -4,6 +4,7 @@
 using System;
 using System.Collections.Generic;
 using System.Linq;
+using Microsoft.Extensions.Internal;
 
 namespace Microsoft.DotNet.ProjectModel.Compilation
 {
@@ -19,5 +20,27 @@ namespace Microsoft.DotNet.ProjectModel.Compilation
             RelativePath = relativePath;
             ResolvedPath = resolvedPath;
         }
+
+        public bool Equals(LibraryAsset other)
+        {
+            return string.Equals(Name, other.Name)
+                && string.Equals(RelativePath, other.RelativePath)
+                && string.Equals(ResolvedPath, other.ResolvedPath);
+        }
+
+        public override bool Equals(object obj)
+        {
+            if (ReferenceEquals(null, obj)) return false;
+            return obj is LibraryAsset && Equals((LibraryAsset) obj);
+        }
+
+        public override int GetHashCode()
+        {
+            var combiner = HashCodeCombiner.Start();
+            combiner.Add(Name);
+            combiner.Add(RelativePath);
+            combiner.Add(ResolvedPath);
+            return combiner.CombinedHash;
+        }
     }
 }
diff --git a/src/Microsoft.Extensions.DependencyModel/CompilationLibrary.cs b/src/Microsoft.Extensions.DependencyModel/CompilationLibrary.cs
index ea754d876..5eee6fa5a 100644
--- a/src/Microsoft.Extensions.DependencyModel/CompilationLibrary.cs
+++ b/src/Microsoft.Extensions.DependencyModel/CompilationLibrary.cs
@@ -5,6 +5,7 @@ using System;
 using System.Collections.Generic;
 using System.IO;
 using System.Reflection;
+using Microsoft.Extensions.PlatformAbstractions;
 
 namespace Microsoft.Extensions.DependencyModel
 {
@@ -12,6 +13,10 @@ namespace Microsoft.Extensions.DependencyModel
     {
         private static Lazy<Assembly> _entryAssembly = new Lazy<Assembly>(GetEntryAssembly);
 
+        private static string _nugetPackages = Environment.GetEnvironmentVariable("NUGET_PACKAGES") ?? GetDefaultPackageDirectory();
+
+        private static string _packageCache = Environment.GetEnvironmentVariable("DOTNET_PACKAGES_CACHE");
+
         public CompilationLibrary(string libraryType, string packageName, string version, string hash, string[] assemblies, Dependency[] dependencies, bool serviceable)
             : base(libraryType, packageName, version, hash,  dependencies, serviceable)
         {
@@ -24,24 +29,126 @@ namespace Microsoft.Extensions.DependencyModel
         {
             var entryAssembly = _entryAssembly.Value;
             var entryAssemblyName = entryAssembly.GetName().Name;
-            var basePath = GetRefsLocation();
 
-            foreach (var assembly in Assemblies)
+            string basePath;
+            string fullName;
+
+            var appBase = Path.GetDirectoryName(entryAssembly.Location);
+            var refsDir = Path.Combine(appBase, "refs");
+            var hasRefs = Directory.Exists(refsDir);
+            var isProject = string.Equals(LibraryType, "project", StringComparison.OrdinalIgnoreCase);
+
+            if (hasRefs || isProject)
             {
-                if (Path.GetFileNameWithoutExtension(assembly) == entryAssemblyName)
+                foreach (var assembly in Assemblies)
                 {
-                    yield return entryAssembly.Location;
-                    continue;
+                    var assemblyFile = Path.GetFileName(assembly);
+                    if (hasRefs && TryResolveAssemblyFile(refsDir, assemblyFile, out fullName))
+                    {
+                        yield return fullName;
+                    }
+                    else if (TryResolveAssemblyFile(appBase, assemblyFile, out fullName))
+                    {
+                        yield return fullName;
+                    }
+                    else
+                    {
+                        var errorMessage = $"Can not find assembly file {assemblyFile} at '{appBase}'";
+                        if (hasRefs)
+                        {
+                            errorMessage += $", '{refsDir}'";
+                        }
+                        throw new InvalidOperationException(errorMessage);
+                    }
+                }
+                yield break;
+            }
+            else if (TryResolvePackagePath(out basePath))
+            {
+                foreach (var assembly in Assemblies)
+                {
+                    if (!TryResolveAssemblyFile(basePath, assembly, out fullName))
+                    {
+                        throw new InvalidOperationException($"Can not find assembly file at '{fullName}'");
+                    }
+                    yield return fullName;
+                }
+                yield break;
+            }
+            throw new InvalidOperationException($"Can not find compilation library location for package '{PackageName}'");
+        }
+
+        private bool TryResolveAssemblyFile(string basePath, string assemblyPath, out string fullName)
+        {
+            fullName = Path.Combine(basePath, assemblyPath);
+            if (File.Exists(fullName))
+            {
+                return true;
+            }
+            return false;
+        }
+
+        private bool TryResolvePackagePath(out string packagePath)
+        {
+            packagePath = null;
+
+            if (!string.IsNullOrEmpty(_packageCache))
+            {
+                var hashSplitterPos = Hash.IndexOf('-');
+                if (hashSplitterPos <= 0 || hashSplitterPos == Hash.Length - 1)
+                {
+                    throw new InvalidOperationException($"Invalid hash entry '{Hash}' for package '{PackageName}'");
                 }
 
-                var fullName = Path.Combine(basePath, Path.GetFileName(assembly));
-                if (!File.Exists(fullName))
+                var hashAlgorithm = Hash.Substring(0, hashSplitterPos);
+
+                var cacheHashPath = Path.Combine(_packageCache, $"{PackageName}.{Version}.nupkg.{hashAlgorithm}");
+
+                if (File.Exists(cacheHashPath) &&
+                    File.ReadAllText(cacheHashPath) == Hash.Substring(hashSplitterPos + 1))
                 {
-                    throw new InvalidOperationException($"Can not resolve assembly {assembly} location");
+                    if (TryResolvePackagePath(_nugetPackages, out packagePath))
+                    {
+                        return true;
+                    }
                 }
-                yield return fullName;
             }
+            if (!string.IsNullOrEmpty(_nugetPackages) &&
+                TryResolvePackagePath(_nugetPackages, out packagePath))
+            {
+                return true;
+            }
+            return false;
         }
+
+        private bool TryResolvePackagePath(string basePath, out string packagePath)
+        {
+            packagePath = Path.Combine(basePath, PackageName, Version);
+            if (Directory.Exists(packagePath))
+            {
+                return true;
+            }
+            return false;
+        }
+
+        private static string GetDefaultPackageDirectory()
+        {
+            string basePath;
+            if (PlatformServices.Default.Runtime.OperatingSystemPlatform == Platform.Windows)
+            {
+                basePath = Environment.GetEnvironmentVariable("USERPROFILE");
+            }
+            else
+            {
+                basePath = Environment.GetEnvironmentVariable("HOME");
+            }
+            if (string.IsNullOrEmpty(basePath))
+            {
+                return null;
+            }
+            return Path.Combine(basePath, ".nuget", "packages");
+        }
+
         private static Assembly GetEntryAssembly()
         {
             var entryAssembly = (Assembly)typeof(Assembly).GetTypeInfo().GetDeclaredMethod("GetEntryAssembly").Invoke(null, null);
@@ -51,10 +158,5 @@ namespace Microsoft.Extensions.DependencyModel
             }
             return entryAssembly;
         }
-
-        private static string GetRefsLocation()
-        {
-            return Path.Combine(Path.GetDirectoryName(_entryAssembly.Value.Location), "refs");
-        }
     }
 }
\ No newline at end of file
diff --git a/src/Microsoft.Extensions.DependencyModel/project.json b/src/Microsoft.Extensions.DependencyModel/project.json
index 622f7ef3b..8e5cca5d4 100644
--- a/src/Microsoft.Extensions.DependencyModel/project.json
+++ b/src/Microsoft.Extensions.DependencyModel/project.json
@@ -10,7 +10,8 @@
     "keyFile": "../../tools/Key.snk"
   },
   "dependencies": {
-    "Newtonsoft.Json": "7.0.1"
+    "Newtonsoft.Json": "7.0.1",
+    "Microsoft.Extensions.PlatformAbstractions": "1.0.0-rc2-16530"
   },
   "frameworks": {
     "net451": { },
diff --git a/src/dotnet-compile/Program.cs b/src/dotnet-compile/Program.cs
index 7c5ea08e2..cdbd9ec57 100644
--- a/src/dotnet-compile/Program.cs
+++ b/src/dotnet-compile/Program.cs
@@ -249,18 +249,6 @@ namespace Microsoft.DotNet.Tools.Compiler
                 }
 
                 compilerArgs.Add($"--resource:\"{depsJsonFile},{context.ProjectFile.Name}.deps.json\"");
-
-                var refsFolder = Path.Combine(outputPath, "refs");
-                if (Directory.Exists(refsFolder))
-                {
-                    Directory.Delete(refsFolder, true);
-                }
-
-                Directory.CreateDirectory(refsFolder);
-                foreach (var reference in references)
-                {
-                    File.Copy(reference, Path.Combine(refsFolder, Path.GetFileName(reference)));
-                }
             }
 
             if (!AddNonCultureResources(context.ProjectFile, compilerArgs, intermediateOutputPath))
diff --git a/src/dotnet-publish/PublishCommand.cs b/src/dotnet-publish/PublishCommand.cs
index 50a6280ec..e2d2f0d67 100644
--- a/src/dotnet-publish/PublishCommand.cs
+++ b/src/dotnet-publish/PublishCommand.cs
@@ -133,6 +133,11 @@ namespace Microsoft.DotNet.Tools.Publish
                 PublishFiles(export.RuntimeAssemblies, outputPath, nativeSubdirectories: false);
                 PublishFiles(export.NativeLibraries, outputPath, nativeSubdirectories);
                 PublishFiles(export.RuntimeAssets, outputPath);
+
+                if (options.PreserveCompilationContext.GetValueOrDefault())
+                {
+                    PublishRefs(export, outputPath);
+                }
             }
 
             CopyContents(context, outputPath);
@@ -151,6 +156,26 @@ namespace Microsoft.DotNet.Tools.Publish
             return true;
         }
 
+        private static void PublishRefs(LibraryExport export, string outputPath)
+        {
+            var refsPath = Path.Combine(outputPath, "refs");
+            if (!Directory.Exists(refsPath))
+            {
+                Directory.CreateDirectory(refsPath);
+            }
+
+            // Do not copy compilation assembly if it's in runtime assemblies
+            var runtimeAssemblies = new HashSet<LibraryAsset>(export.RuntimeAssemblies);
+            foreach (var compilationAssembly in export.CompilationAssemblies)
+            {
+                if (!runtimeAssemblies.Contains(compilationAssembly))
+                {
+                    var destFileName = Path.Combine(refsPath, Path.GetFileName(compilationAssembly.ResolvedPath));
+                    File.Copy(compilationAssembly.ResolvedPath, destFileName, overwrite: true);
+                }
+            }
+        }
+
         private static int PublishHost(ProjectContext context, string outputPath)
         {
             if (context.TargetFramework.IsDesktop())
diff --git a/test/TestProjects/TestAppCompilationContext/NuGet.Config b/test/TestProjects/TestAppCompilationContext/NuGet.Config
new file mode 100644
index 000000000..d35fb92ab
--- /dev/null
+++ b/test/TestProjects/TestAppCompilationContext/NuGet.Config
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<configuration>
+  <packageSources>
+    <!--To inherit the global NuGet package sources remove the <clear/> line below -->
+    <clear />
+    <add key="dotnet-core" value="https://www.myget.org/F/dotnet-core/api/v3/index.json" />
+    <add key="nugetbuild" value="https://www.myget.org/F/nugetbuild/api/v3/index.json" />
+    <add key="AspNetCIDev" value="https://www.myget.org/F/aspnetcidev/api/v3/index.json" />
+    <add key="roslyn-nightly" value="https://www.myget.org/F/roslyn-nightly/api/v3/index.json" />
+    <add key="api.nuget.org" value="https://api.nuget.org/v3/index.json" />
+    <add key="dotnet-corefxlab" value="https://www.myget.org/F/dotnet-corefxlab/api/v3/index.json" />
+    <add key="corefxlab" value="https://www.myget.org/F/netcore-package-prototyping/api/v3/index.json" />
+    <add key="corert" value="https://www.myget.org/F/dotnet/api/v2" />
+    <add key="dotnet-buildtools" value="https://www.myget.org/F/dotnet-buildtools/api/v3/index.json" />
+    <add key="fsharp-daily" value="https://www.myget.org/F/fsharp-daily/api/v3/index.json" />
+  </packageSources>
+  <activePackageSource>
+    <add key="AspNetCIDev" value="https://www.myget.org/F/aspnetcidev/api/v3/index.json" />
+  </activePackageSource>
+</configuration>
diff --git a/test/TestProjects/TestAppCompilationContext/Program.cs b/test/TestProjects/TestAppCompilationContext/Program.cs
new file mode 100644
index 000000000..ac3163a58
--- /dev/null
+++ b/test/TestProjects/TestAppCompilationContext/Program.cs
@@ -0,0 +1,17 @@
+// Copyright (c) .NET Foundation and contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+using System;
+using System.Diagnostics;
+
+namespace TestApp
+{
+    public class Program
+    {
+        public static int Main(string[] args)
+        {
+            Console.WriteLine(TestLibrary.Helper.GetMessage());
+            return 100;
+        }
+    }
+}
diff --git a/test/TestProjects/TestAppCompilationContext/project.json b/test/TestProjects/TestAppCompilationContext/project.json
new file mode 100644
index 000000000..71beee222
--- /dev/null
+++ b/test/TestProjects/TestAppCompilationContext/project.json
@@ -0,0 +1,23 @@
+{
+    "version": "1.0.0-*",
+    "compilationOptions": {
+        "emitEntryPoint": true,
+        "preserveCompilationContext": true
+    },
+
+    "dependencies": {
+        "TestLibrary": "1.0.0-*",
+
+        "NETStandard.Library": "1.0.0-rc2-23704",
+        "Microsoft.NETCore.Platforms": "1.0.1-rc2-23704"
+    },
+
+    "frameworks": {
+        "dnxcore50": { }
+    },
+
+    "scripts": {
+        "prepublish" : ["echo prepublish_output ?%publish:ProjectPath%? ?%publish:Configuration%? ?%publish:OutputPath%? ?%publish:Framework%? ?%publish:Runtime%?"],
+        "postpublish" : ["echo postpublish_output ?%publish:ProjectPath%? ?%publish:Configuration%? ?%publish:OutputPath%? ?%publish:Framework%? ?%publish:Runtime%?"]
+    }
+}
diff --git a/test/dotnet-publish.Tests/Microsoft.DotNet.Tools.Publish.Tests.cs b/test/dotnet-publish.Tests/Microsoft.DotNet.Tools.Publish.Tests.cs
index a883591aa..2d7444248 100644
--- a/test/dotnet-publish.Tests/Microsoft.DotNet.Tools.Publish.Tests.cs
+++ b/test/dotnet-publish.Tests/Microsoft.DotNet.Tools.Publish.Tests.cs
@@ -169,6 +169,37 @@ namespace Microsoft.DotNet.Tools.Publish.Tests
             publishCommand.GetOutputDirectory().Should().HaveFile("Newtonsoft.Json.dll");
         }
 
+        [Fact]
+        public void RefsPublishTest()
+        {
+            // create unique directories in the 'temp' folder
+            var root = Temp.CreateDirectory();
+            root.CopyFile(Path.Combine(_testProjectsRoot, "global.json"));
+            var testAppDir = root.CreateDirectory("TestAppCompilationContext");
+            var testLibDir = root.CreateDirectory("TestLibrary");
+
+            // copy projects to the temp dir
+            CopyProjectToTempDir(Path.Combine(_testProjectsRoot, "TestAppCompilationContext"), testAppDir);
+            CopyProjectToTempDir(Path.Combine(_testProjectsRoot, "TestLibrary"), testLibDir);
+
+            RunRestore(testAppDir.Path);
+            RunRestore(testLibDir.Path);
+
+            var testProject = GetProjectPath(testAppDir);
+            var publishCommand = new PublishCommand(testProject);
+            publishCommand.Execute().Should().Pass();
+
+            publishCommand.GetOutputDirectory().Should().HaveFile("TestAppCompilationContext.dll");
+            publishCommand.GetOutputDirectory().Should().HaveFile("TestLibrary.dll");
+
+            var refsDirectory = new DirectoryInfo(Path.Combine(publishCommand.GetOutputDirectory().FullName, "refs"));
+            // Should have compilation time assemblies
+            refsDirectory.Should().HaveFile("System.IO.dll");
+            // Libraries in which lib==ref should be deduped
+            refsDirectory.Should().NotHaveFile("TestLibrary.dll");
+        }
+
+
         [Fact]
         public void CompilationFailedTest()
         {