diff --git a/chrome/browser/cocoa/browser_window_cocoa.h b/chrome/browser/cocoa/browser_window_cocoa.h
index 9a46f7de1c8be0be7610e071faf4a11fe417c9b1..5722fff546a2be0ef776b2dc57c0799210389ba3 100644
--- a/chrome/browser/cocoa/browser_window_cocoa.h
+++ b/chrome/browser/cocoa/browser_window_cocoa.h
@@ -107,6 +107,7 @@ class BrowserWindowCocoa : public BrowserWindow,
   virtual void Paste();
   virtual void ToggleTabStripMode();
   virtual void OpenTabpose();
+  virtual void PrepareForInstant();
   virtual void ShowInstant(TabContents* preview_contents);
   virtual void HideInstant();
   virtual gfx::Rect GetInstantBounds();
diff --git a/chrome/browser/cocoa/browser_window_cocoa.mm b/chrome/browser/cocoa/browser_window_cocoa.mm
index 5e21af0f0fb4041f429297bc6ccfaa241b68bf41..8695325d884b836129be66fcfa4517424e237323 100644
--- a/chrome/browser/cocoa/browser_window_cocoa.mm
+++ b/chrome/browser/cocoa/browser_window_cocoa.mm
@@ -577,6 +577,10 @@ void BrowserWindowCocoa::OpenTabpose() {
   [controller_ openTabpose];
 }
 
+void BrowserWindowCocoa::PrepareForInstant() {
+  // TODO: implement fade as done on windows.
+}
+
 void BrowserWindowCocoa::ShowInstant(TabContents* preview_contents) {
   [controller_ showInstant:preview_contents];
 }
diff --git a/chrome/browser/gtk/browser_window_gtk.cc b/chrome/browser/gtk/browser_window_gtk.cc
index 6d537c96a6930fe4e531dc11e71fc82a3b28256d..d7ea5fb87b61fedf9e42bc8227e60d0c7b7b2865 100644
--- a/chrome/browser/gtk/browser_window_gtk.cc
+++ b/chrome/browser/gtk/browser_window_gtk.cc
@@ -1127,6 +1127,10 @@ void BrowserWindowGtk::Paste() {
   DoCutCopyPaste(this, &RenderViewHost::Paste, "paste-clipboard");
 }
 
+void BrowserWindowGtk::PrepareForInstant() {
+  // TODO: implement fade as done on windows.
+}
+
 void BrowserWindowGtk::ShowInstant(TabContents* preview_contents) {
   contents_container_->SetPreviewContents(preview_contents);
 }
diff --git a/chrome/browser/gtk/browser_window_gtk.h b/chrome/browser/gtk/browser_window_gtk.h
index ce8e5825f979cd65e4163570cf3744e78dc63711..7711a2a26eb11f16d9e067d17c854ba5b30b5dd4 100644
--- a/chrome/browser/gtk/browser_window_gtk.h
+++ b/chrome/browser/gtk/browser_window_gtk.h
@@ -125,6 +125,7 @@ class BrowserWindowGtk : public BrowserWindow,
   virtual void Copy();
   virtual void Paste();
   virtual void ToggleTabStripMode() {}
+  virtual void PrepareForInstant();
   virtual void ShowInstant(TabContents* preview_contents);
   virtual void HideInstant();
   virtual gfx::Rect GetInstantBounds();
diff --git a/chrome/browser/instant/instant_controller.cc b/chrome/browser/instant/instant_controller.cc
index 151308c538ab07c28988c54d03ed55faabfb22a7..001e238e7e57cdf505e51352195570a6040338c2 100644
--- a/chrome/browser/instant/instant_controller.cc
+++ b/chrome/browser/instant/instant_controller.cc
@@ -93,6 +93,9 @@ void InstantController::Update(TabContents* tab_contents,
   if (!loader_manager_.get())
     loader_manager_.reset(new InstantLoaderManager(this));
 
+  if (!is_active_)
+    delegate_->PrepareForInstant();
+
   if (ShouldUpdateNow(template_url_id, match.destination_url)) {
     UpdateLoader(template_url, match.destination_url, match.transition,
                  user_text, suggested_text);
diff --git a/chrome/browser/instant/instant_delegate.h b/chrome/browser/instant/instant_delegate.h
index a5c922359c7c210f67a3bbb840519286381712d4..90f58a2cf6925c8bc983e6ac2da455d8b8e53ac0 100644
--- a/chrome/browser/instant/instant_delegate.h
+++ b/chrome/browser/instant/instant_delegate.h
@@ -18,6 +18,11 @@ class Rect;
 // InstantController for details.
 class InstantDelegate {
  public:
+  // Invoked when instant starts loading, but before the preview tab contents is
+  // ready to be shown. This may be used to animate between the states.
+  // This is followed by ShowInstant and/or HideInstant.
+  virtual void PrepareForInstant() = 0;
+
   // Invoked when the instant TabContents should be shown.
   virtual void ShowInstant(TabContents* preview_contents) = 0;
 
diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc
index 3d8f3c58817471e6b3de4e7720c35a2efc163ddc..5f31db8d62f90022bab3f17cfe325ce09b80dfa1 100644
--- a/chrome/browser/ui/browser.cc
+++ b/chrome/browser/ui/browser.cc
@@ -26,9 +26,6 @@
 #include "gfx/point.h"
 #include "chrome/app/chrome_command_ids.h"
 #include "chrome/browser/autofill/autofill_manager.h"
-#if defined(OS_WIN)
-#include "chrome/browser/autofill/autofill_ie_toolbar_import_win.h"
-#endif  // defined(OS_WIN)
 #include "chrome/browser/bookmarks/bookmark_model.h"
 #include "chrome/browser/bookmarks/bookmark_utils.h"
 #include "chrome/browser/browser_list.h"
@@ -115,6 +112,7 @@
 
 #if defined(OS_WIN)
 #include "app/win_util.h"
+#include "chrome/browser/autofill/autofill_ie_toolbar_import_win.h"
 #include "chrome/browser/browser_child_process_host.h"
 #include "chrome/browser/cert_store.h"
 #include "chrome/browser/download/save_package.h"
@@ -3337,6 +3335,10 @@ void Browser::OnStateChanged() {
 ///////////////////////////////////////////////////////////////////////////////
 // Browser, InstantDelegate implementation:
 
+void Browser::PrepareForInstant() {
+  window_->PrepareForInstant();
+}
+
 void Browser::ShowInstant(TabContents* preview_contents) {
   DCHECK(instant_->tab_contents() == GetSelectedTabContents());
   window_->ShowInstant(preview_contents);
diff --git a/chrome/browser/ui/browser.h b/chrome/browser/ui/browser.h
index abd2be99be1fa287c19c756883cb83837d14e39d..25e705eb9738fb42ad0190972c4ee37dcf1f61d4 100644
--- a/chrome/browser/ui/browser.h
+++ b/chrome/browser/ui/browser.h
@@ -773,6 +773,7 @@ class Browser : public TabHandlerDelegate,
   virtual void OnStateChanged();
 
   // Overriden from InstantDelegate:
+  virtual void PrepareForInstant();
   virtual void ShowInstant(TabContents* preview_contents);
   virtual void HideInstant();
   virtual void CommitInstant(TabContents* preview_contents);
diff --git a/chrome/browser/ui/browser_window.h b/chrome/browser/ui/browser_window.h
index c365a27f0ecc0b79bc9b7b1f30ffb62b93f58bd4..aa3a931db2894a8b26a684a3d1ca19a3d3d97286 100644
--- a/chrome/browser/ui/browser_window.h
+++ b/chrome/browser/ui/browser_window.h
@@ -322,6 +322,9 @@ class BrowserWindow {
   virtual void OpenTabpose() = 0;
 #endif
 
+  // See InstantDelegate for details.
+  virtual void PrepareForInstant() = 0;
+
   // Invoked when instant's tab contents should be shown.
   virtual void ShowInstant(TabContents* preview_contents) = 0;
 
diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc
index 25d8467da6d11230c666fbc4b29fdbc711836822..2629725c111d58af2aed66fa7b399c9e0afdd281 100644
--- a/chrome/browser/ui/views/frame/browser_view.cc
+++ b/chrome/browser/ui/views/frame/browser_view.cc
@@ -1362,11 +1362,24 @@ void BrowserView::ToggleTabStripMode() {
   frame_->TabStripDisplayModeChanged();
 }
 
+void BrowserView::PrepareForInstant() {
+  contents_->FadeActiveContents();
+}
+
 void BrowserView::ShowInstant(TabContents* preview_contents) {
   if (!preview_container_)
     preview_container_ = new TabContentsContainer();
   contents_->SetPreview(preview_container_, preview_contents);
   preview_container_->ChangeTabContents(preview_contents);
+
+#if defined(OS_WIN)
+  // Removing the fade is instant (on windows). We need to force the preview to
+  // draw, otherwise the current page flickers before the new page appears.
+  RedrawWindow(preview_contents->view()->GetContentNativeView(), NULL, NULL,
+               RDW_INVALIDATE | RDW_UPDATENOW | RDW_NOCHILDREN);
+#endif
+
+  contents_->RemoveFade();
 }
 
 void BrowserView::HideInstant() {
@@ -1378,6 +1391,7 @@ void BrowserView::HideInstant() {
   contents_->SetPreview(NULL, NULL);
   delete preview_container_;
   preview_container_ = NULL;
+  contents_->RemoveFade();
 }
 
 gfx::Rect BrowserView::GetInstantBounds() {
diff --git a/chrome/browser/ui/views/frame/browser_view.h b/chrome/browser/ui/views/frame/browser_view.h
index 8a443bb8e62e4448a0cfa93f9187a0224772653e..f57a2d3481edf8b4c0a2ccdc332049d9be40ae7c 100644
--- a/chrome/browser/ui/views/frame/browser_view.h
+++ b/chrome/browser/ui/views/frame/browser_view.h
@@ -319,6 +319,7 @@ class BrowserView : public BrowserBubbleHost,
   virtual void Copy();
   virtual void Paste();
   virtual void ToggleTabStripMode();
+  virtual void PrepareForInstant();
   virtual void ShowInstant(TabContents* preview_contents);
   virtual void HideInstant();
   virtual gfx::Rect GetInstantBounds();
diff --git a/chrome/browser/ui/views/frame/contents_container.cc b/chrome/browser/ui/views/frame/contents_container.cc
index c3056f794c1bae32a7fef3a4d53838dd82a89b5b..084c87f7cda3e1f73fb423c599a5c9d027497a95 100644
--- a/chrome/browser/ui/views/frame/contents_container.cc
+++ b/chrome/browser/ui/views/frame/contents_container.cc
@@ -4,18 +4,33 @@
 
 #include "chrome/browser/views/frame/contents_container.h"
 
+#include "app/slide_animation.h"
+#include "third_party/skia/include/core/SkColor.h"
+#include "views/background.h"
+#include "views/widget/root_view.h"
+#include "views/widget/widget.h"
+
+// Min/max opacity of the overlay.
+static const int kMinOpacity = 0;
+static const int kMaxOpacity = 192;
+
 ContentsContainer::ContentsContainer(views::View* active)
     : active_(active),
       preview_(NULL),
       preview_tab_contents_(NULL),
+      active_overlay_(NULL),
       active_top_margin_(0) {
   AddChildView(active_);
 }
 
 ContentsContainer::~ContentsContainer() {
+  // We don't need to explicitly delete active_overlay_ as it'll be deleted by
+  // virtue of being a child window.
 }
 
 void ContentsContainer::MakePreviewContentsActiveContents() {
+  RemoveFade();
+
   active_ = preview_;
   preview_ = NULL;
   Layout();
@@ -52,6 +67,53 @@ gfx::Rect ContentsContainer::GetPreviewBounds() {
   return gfx::Rect(screen_loc, size());
 }
 
+void ContentsContainer::FadeActiveContents() {
+  if (active_overlay_)
+    return;
+
+#if !defined(OS_WIN)
+  // TODO: fix this. I'm disabling as z-order isn't right on linux so that
+  // overlay ends up obscuring the omnibox.
+  return;
+#endif
+
+  overlay_animation_.reset(new SlideAnimation(this));
+  overlay_animation_->SetDuration(300);
+  overlay_animation_->SetSlideDuration(300);
+  overlay_animation_->Show();
+
+  active_overlay_ = views::Widget::CreatePopupWidget(views::Widget::Transparent,
+                                              views::Widget::NotAcceptEvents,
+                                              views::Widget::DeleteOnDestroy,
+                                              views::Widget::MirrorOriginInRTL);
+  active_overlay_->SetOpacity(0);
+  gfx::Point screen_origin;
+  views::View::ConvertPointToScreen(active_, &screen_origin);
+  gfx::Rect overlay_bounds(screen_origin, active_->size());
+  active_overlay_->Init(active_->GetWidget()->GetNativeView(), overlay_bounds);
+  views::View* content_view = new views::View();
+  content_view->set_background(
+      views::Background::CreateSolidBackground(SK_ColorWHITE));
+  active_overlay_->SetContentsView(content_view);
+  active_overlay_->Show();
+  active_overlay_->MoveAbove(active_->GetWidget());
+}
+
+void ContentsContainer::RemoveFade() {
+  overlay_animation_.reset();
+  if (active_overlay_) {
+    active_overlay_->Close();
+    active_overlay_ = NULL;
+  }
+}
+
+void ContentsContainer::AnimationProgressed(const Animation* animation) {
+  active_overlay_->SetOpacity(
+      Tween::ValueBetween(animation->GetCurrentValue(), kMinOpacity,
+                          kMaxOpacity));
+  active_overlay_->GetRootView()->SchedulePaint();
+}
+
 void ContentsContainer::Layout() {
   // The active view always gets the full bounds.
   active_->SetBounds(0, active_top_margin_, width(),
diff --git a/chrome/browser/ui/views/frame/contents_container.h b/chrome/browser/ui/views/frame/contents_container.h
index 8943f0a66e58466c1bcab1e825ec7387eb64a819..9f25c6b0a7eb1634dda463af4bfef8db645a3792 100644
--- a/chrome/browser/ui/views/frame/contents_container.h
+++ b/chrome/browser/ui/views/frame/contents_container.h
@@ -6,14 +6,21 @@
 #define CHROME_BROWSER_UI_VIEWS_FRAME_CONTENTS_CONTAINER_H_
 #pragma once
 
+#include "app/animation.h"
+#include "base/scoped_ptr.h"
 #include "views/view.h"
 
+class SlideAnimation;
 class TabContents;
 
+namespace views {
+class Widget;
+}
+
 // ContentsContainer is responsible for managing the TabContents views.
 // ContentsContainer has up to two children: one for the currently active
 // TabContents and one for instant's TabContents.
-class ContentsContainer : public views::View {
+class ContentsContainer : public views::View, public AnimationDelegate {
  public:
   explicit ContentsContainer(views::View* active);
   virtual ~ContentsContainer();
@@ -35,9 +42,18 @@ class ContentsContainer : public views::View {
   // retuns the bounds the preview would be shown at.
   gfx::Rect GetPreviewBounds();
 
+  // Fades out the active contents.
+  void FadeActiveContents();
+
+  // Removes the fade. This is done implicitly when the preview is made active.
+  void RemoveFade();
+
   // View overrides:
   virtual void Layout();
 
+  // AnimationDelegate overrides:
+  virtual void AnimationProgressed(const Animation* animation);
+
  private:
   views::View* active_;
 
@@ -45,6 +61,13 @@ class ContentsContainer : public views::View {
 
   TabContents* preview_tab_contents_;
 
+  // Translucent Widget positioned right above the active view that is used to
+  // make the active view appear faded out.
+  views::Widget* active_overlay_;
+
+  // Animation used to vary the opacity of active_overlay.
+  scoped_ptr<SlideAnimation> overlay_animation_;
+
   // The margin between the top and the active view. This is used to make the
   // preview overlap the bookmark bar on the new tab page.
   int active_top_margin_;
diff --git a/chrome/test/test_browser_window.h b/chrome/test/test_browser_window.h
index c54deac0e507ed9726674b02c81d14995baaceeb..e60952e7b63327c2a13987194c389d0494739b41 100644
--- a/chrome/test/test_browser_window.h
+++ b/chrome/test/test_browser_window.h
@@ -103,6 +103,7 @@ class TestBrowserWindow : public BrowserWindow {
   virtual void Paste() {}
   virtual void ToggleTabStripMode() {}
   virtual void OpenTabpose() {}
+  virtual void PrepareForInstant() {}
   virtual void ShowInstant(TabContents* preview_contents) {}
   virtual void HideInstant() {}
   virtual gfx::Rect GetInstantBounds() { return gfx::Rect(); }