diff --git a/java/res/layout/setup_welcome_screen.xml b/java/res/layout/setup_welcome_screen.xml
new file mode 100644
index 0000000000000000000000000000000000000000..44e98e2685ca53f5d6a540988c6a74c67b0671db
--- /dev/null
+++ b/java/res/layout/setup_welcome_screen.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical">
+    <include layout="@layout/setup_welcome_title" />
+    <include layout="@layout/setup_welcome_video" />
+</LinearLayout>
diff --git a/java/res/layout/setup_welcome_title.xml b/java/res/layout/setup_welcome_title.xml
new file mode 100644
index 0000000000000000000000000000000000000000..6e6d78147aab149206d781269b630a5c73cb2824
--- /dev/null
+++ b/java/res/layout/setup_welcome_title.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<merge xmlns:android="http://schemas.android.com/apk/res/android">
+    <TextView
+        android:id="@+id/setup_welcome_title"
+        style="@style/setupTitleStyle"
+        android:layout_alignParentLeft="true"
+        android:layout_alignParentTop="true" />
+    <TextView
+        android:id="@+id/setup_welcome_description"
+        android:text="@string/setup_welcome_additional_description"
+        android:layout_marginTop="12dp"
+        style="@style/setupWelcomeDescritpionStyle" />
+</merge>
diff --git a/java/res/layout/setup_welcome_video.xml b/java/res/layout/setup_welcome_video.xml
new file mode 100644
index 0000000000000000000000000000000000000000..a72fbd72f5cd6486663db6251edbe33adc357b44
--- /dev/null
+++ b/java/res/layout/setup_welcome_video.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<merge xmlns:android="http://schemas.android.com/apk/res/android">
+    <VideoView
+        android:id="@+id/setup_welcome_video"
+        android:layout_margin="36dp"
+        android:layout_width="240dp"
+        android:layout_height="150dp"
+        android:layout_centerHorizontal="true" />
+    <com.android.inputmethod.latin.setup.SetupStartIndicatorView
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content" />
+</merge>
diff --git a/java/res/layout/setup_wizard.xml b/java/res/layout/setup_wizard.xml
index 1cf19d299313925690cf1127de52f213e8adc426..e766e4cbbc53b814055133522c1bc2af2d35dd20 100644
--- a/java/res/layout/setup_wizard.xml
+++ b/java/res/layout/setup_wizard.xml
@@ -26,6 +26,9 @@
     android:paddingRight="@dimen/setup_horizontal_padding"
     android:paddingTop="16dp"
     android:paddingBottom="16dp">
+    <include
+        android:id="@+id/setup_welcome_screen"
+        layout="@layout/setup_welcome_screen" />
     <include
         android:id="@+id/setup_steps_screen"
         layout="@layout/setup_steps_screen" />
diff --git a/java/res/raw/setup_welcome_video.mp4 b/java/res/raw/setup_welcome_video.mp4
new file mode 100644
index 0000000000000000000000000000000000000000..09357d8de22e3f57ea529d1467a97b9491d1b209
Binary files /dev/null and b/java/res/raw/setup_welcome_video.mp4 differ
diff --git a/java/src/com/android/inputmethod/latin/setup/SetupActivity.java b/java/src/com/android/inputmethod/latin/setup/SetupActivity.java
index 7b38c70e2402240e686d7c7632755c7d61586c64..a7a41719e414ce270261f940e2df0fb46b8d6bc9 100644
--- a/java/src/com/android/inputmethod/latin/setup/SetupActivity.java
+++ b/java/src/com/android/inputmethod/latin/setup/SetupActivity.java
@@ -17,9 +17,12 @@
 package com.android.inputmethod.latin.setup;
 
 import android.app.Activity;
+import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.res.Resources;
+import android.media.MediaPlayer;
+import android.net.Uri;
 import android.os.Bundle;
 import android.os.Message;
 import android.provider.Settings;
@@ -27,6 +30,7 @@ import android.view.View;
 import android.view.inputmethod.InputMethodInfo;
 import android.view.inputmethod.InputMethodManager;
 import android.widget.TextView;
+import android.widget.VideoView;
 
 import com.android.inputmethod.compat.TextViewCompatUtils;
 import com.android.inputmethod.compat.ViewCompatUtils;
@@ -40,14 +44,21 @@ import java.util.HashMap;
 
 // TODO: Use Fragment to implement welcome screen and setup steps.
 public final class SetupActivity extends Activity implements View.OnClickListener {
+    private View mWelcomeScreen;
+    private View mSetupScreen;
     private SetupStepIndicatorView mStepIndicatorView;
+    private Uri mWelcomeVideoUri;
+    private VideoView mWelcomeVideoView;
+    private View mActionStart;
     private TextView mActionFinish;
     private final SetupStepGroup mSetupStepGroup = new SetupStepGroup();
     private static final String STATE_STEP = "step";
     private int mStepNumber;
+    private static final int STEP_0 = 0;
     private static final int STEP_1 = 1;
     private static final int STEP_2 = 2;
     private static final int STEP_3 = 3;
+    private boolean mWasLanguageAndInputSettingsInvoked;
 
     private final SettingsPoolingHandler mHandler = new SettingsPoolingHandler(this);
 
@@ -109,8 +120,13 @@ public final class SetupActivity extends Activity implements View.OnClickListene
             return;
         }
 
-        final TextView stepsTitle = (TextView)findViewById(R.id.setup_title);
         final String applicationName = getResources().getString(getApplicationInfo().labelRes);
+        mWelcomeScreen = findViewById(R.id.setup_welcome_screen);
+        final TextView welcomeTitle = (TextView)findViewById(R.id.setup_welcome_title);
+        welcomeTitle.setText(getString(R.string.setup_welcome_title, applicationName));
+
+        mSetupScreen = findViewById(R.id.setup_steps_screen);
+        final TextView stepsTitle = (TextView)findViewById(R.id.setup_title);
         stepsTitle.setText(getString(R.string.setup_steps_title, applicationName));
 
         mStepIndicatorView = (SetupStepIndicatorView)findViewById(R.id.setup_step_indicator);
@@ -154,6 +170,21 @@ public final class SetupActivity extends Activity implements View.OnClickListene
         });
         mSetupStepGroup.addStep(STEP_3, step3);
 
+        mWelcomeVideoUri = new Uri.Builder()
+                .scheme(ContentResolver.SCHEME_ANDROID_RESOURCE)
+                .authority(getPackageName())
+                .path(Integer.toString(R.raw.setup_welcome_video))
+                .build();
+        mWelcomeVideoView = (VideoView)findViewById(R.id.setup_welcome_video);
+        mWelcomeVideoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
+            @Override
+            public void onCompletion(final MediaPlayer mp) {
+                mp.start();
+            }
+        });
+
+        mActionStart = findViewById(R.id.setup_start_label);
+        mActionStart.setOnClickListener(this);
         mActionFinish = (TextView)findViewById(R.id.setup_finish);
         TextViewCompatUtils.setCompoundDrawablesRelativeWithIntrinsicBounds(mActionFinish,
                 getResources().getDrawable(R.drawable.ic_setup_finish), null, null, null);
@@ -162,6 +193,11 @@ public final class SetupActivity extends Activity implements View.OnClickListene
 
     @Override
     public void onClick(final View v) {
+        if (v == mActionStart) {
+            mStepNumber = STEP_1;
+            updateSetupStepView();
+            return;
+        }
         if (v == mActionFinish) {
             finish();
             return;
@@ -190,6 +226,7 @@ public final class SetupActivity extends Activity implements View.OnClickListene
         intent.setAction(Settings.ACTION_INPUT_METHOD_SETTINGS);
         intent.addCategory(Intent.CATEGORY_DEFAULT);
         startActivity(intent);
+        mWasLanguageAndInputSettingsInvoked = true;
     }
 
     private void invokeSubtypeEnablerOfThisIme() {
@@ -240,7 +277,7 @@ public final class SetupActivity extends Activity implements View.OnClickListene
     private int determineSetupStepNumber() {
         mHandler.cancelPollingImeSettings();
         if (!isThisImeEnabled(this)) {
-            return STEP_1;
+            return mWasLanguageAndInputSettingsInvoked ? STEP_1 : STEP_0;
         }
         if (!isThisImeCurrent(this)) {
             return STEP_2;
@@ -278,6 +315,22 @@ public final class SetupActivity extends Activity implements View.OnClickListene
         updateSetupStepView();
     }
 
+    @Override
+    public void onBackPressed() {
+        if (mStepNumber == STEP_1) {
+            mStepNumber = STEP_0;
+            updateSetupStepView();
+            return;
+        }
+        super.onBackPressed();
+    }
+
+    @Override
+    protected void onPause() {
+        mWelcomeVideoView.stopPlayback();
+        super.onPause();
+    }
+
     @Override
     public void onWindowFocusChanged(final boolean hasFocus) {
         super.onWindowFocusChanged(hasFocus);
@@ -289,6 +342,15 @@ public final class SetupActivity extends Activity implements View.OnClickListene
     }
 
     private void updateSetupStepView() {
+        final boolean welcomeScreen = (mStepNumber == STEP_0);
+        mWelcomeScreen.setVisibility(welcomeScreen ? View.VISIBLE : View.GONE);
+        mSetupScreen.setVisibility(welcomeScreen ? View.GONE: View.VISIBLE);
+        if (welcomeScreen) {
+            mWelcomeVideoView.setVideoURI(mWelcomeVideoUri);
+            mWelcomeVideoView.start();
+            return;
+        }
+        mWelcomeVideoView.stopPlayback();
         final int layoutDirection = ViewCompatUtils.getLayoutDirection(mStepIndicatorView);
         mStepIndicatorView.setIndicatorPosition(
                 getIndicatorPosition(mStepNumber, mSetupStepGroup.getTotalStep(), layoutDirection));
diff --git a/java/src/com/android/inputmethod/latin/setup/SetupStartIndicatorView.java b/java/src/com/android/inputmethod/latin/setup/SetupStartIndicatorView.java
new file mode 100644
index 0000000000000000000000000000000000000000..ca974f6b89b89aac8150d0ad4ddaab6387553036
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/setup/SetupStartIndicatorView.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.inputmethod.latin.setup;
+
+import android.content.Context;
+import android.content.res.ColorStateList;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Path;
+import android.util.AttributeSet;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.android.inputmethod.compat.ViewCompatUtils;
+import com.android.inputmethod.latin.R;
+
+public final class SetupStartIndicatorView extends LinearLayout {
+    public SetupStartIndicatorView(final Context context, final AttributeSet attrs) {
+        super(context, attrs);
+        setOrientation(HORIZONTAL);
+        LayoutInflater.from(context).inflate(R.layout.setup_start_indicator_label, this);
+
+        final LabelView labelView = (LabelView)findViewById(R.id.setup_start_label);
+        labelView.setIndicatorView(findViewById(R.id.setup_start_indicator));
+    }
+
+    public static final class LabelView extends TextView {
+        private View mIndicatorView;
+
+        public LabelView(final Context context, final AttributeSet attrs) {
+            super(context, attrs);
+        }
+
+        public void setIndicatorView(final View indicatorView) {
+            mIndicatorView = indicatorView;
+        }
+
+        @Override
+        public void setPressed(final boolean pressed) {
+            super.setPressed(pressed);
+            if (mIndicatorView != null) {
+                mIndicatorView.setPressed(pressed);
+            }
+        }
+    }
+
+    public static final class IndicatorView extends View {
+        private final Path mIndicatorPath = new Path();
+        private final Paint mIndicatorPaint = new Paint();
+        private final ColorStateList mIndicatorColor;
+
+        public IndicatorView(final Context context, final AttributeSet attrs) {
+            super(context, attrs);
+            mIndicatorColor = getResources().getColorStateList(
+                    R.color.setup_step_action_background);
+            mIndicatorPaint.setStyle(Paint.Style.FILL);
+        }
+
+        @Override
+        public void setPressed(final boolean pressed) {
+            super.setPressed(pressed);
+            invalidate();
+        }
+
+        @Override
+        protected void onDraw(final Canvas canvas) {
+            super.onDraw(canvas);
+            final int layoutDirection = ViewCompatUtils.getLayoutDirection(this);
+            final int width = getWidth();
+            final int height = getHeight();
+            final float halfHeight = height / 2.0f;
+            final Path path = mIndicatorPath;
+            path.rewind();
+            if (layoutDirection == ViewCompatUtils.LAYOUT_DIRECTION_RTL) {
+                // Left arrow
+                path.moveTo(width, 0.0f);
+                path.lineTo(0.0f, halfHeight);
+                path.lineTo(width, height);
+            } else { // LAYOUT_DIRECTION_LTR
+                // Right arrow
+                path.moveTo(0.0f, 0.0f);
+                path.lineTo(width, halfHeight);
+                path.lineTo(0.0f, height);
+            }
+            path.close();
+            final int[] stateSet = getDrawableState();
+            final int color = mIndicatorColor.getColorForState(stateSet, 0);
+            mIndicatorPaint.setColor(color);
+            canvas.drawPath(path, mIndicatorPaint);
+        }
+    }
+}