diff --git a/src/panels/profile/ha-change-password-card.js b/src/panels/profile/ha-change-password-card.js
new file mode 100644
index 0000000000..f9e9ae55ce
--- /dev/null
+++ b/src/panels/profile/ha-change-password-card.js
@@ -0,0 +1,149 @@
+import '@polymer/paper-button/paper-button.js';
+import '@polymer/paper-dialog/paper-dialog.js';
+import '@polymer/paper-spinner/paper-spinner.js';
+import '@polymer/paper-card/paper-card.js';
+import { html } from '@polymer/polymer/lib/utils/html-tag.js';
+import { PolymerElement } from '@polymer/polymer/polymer-element.js';
+
+import '../../resources/ha-style.js';
+
+class HaChangePasswordCard extends PolymerElement {
+ static get template() {
+ return html`
+
+
+
+
+
+ [[_errorMsg]]
+
+
+ [[_statusMsg]]
+
+
+
+
+
+
+
+
+`;
+ }
+
+ static get properties() {
+ return {
+ hass: Object,
+
+ _loading: {
+ type: Boolean,
+ value: false,
+ },
+
+ // Error message when can't talk to server etc
+ _statusMsg: String,
+ _errorMsg: String,
+
+ _currentPassword: String,
+ _password1: String,
+ _password2: String,
+ };
+ }
+
+ ready() {
+ super.ready();
+ this.addEventListener('keypress', (ev) => {
+ this._statusMsg = null;
+ if (ev.keyCode === 13) {
+ this._changePassword();
+ }
+ });
+ }
+
+ async _changePassword() {
+ this._statusMsg = null;
+ if (!this._currentPassword || !this._password1 || !this._password2) return;
+
+ if (this._password1 !== this._password2) {
+ this._errorMsg = "New password confirmation doesn't match";
+ return;
+ }
+
+ if (this._currentPassword === this._password1) {
+ this._errorMsg = 'New password must be different than current password';
+ return;
+ }
+
+ this._loading = true;
+ this._errorMsg = null;
+
+ try {
+ await this.hass.callWS({
+ type: 'config/auth_provider/homeassistant/change_password',
+ current_password: this._currentPassword,
+ new_password: this._password1,
+ });
+
+ this.setProperties({
+ _statusMsg: 'Password changed successfully',
+ _currentPassword: null,
+ _password1: null,
+ _password2: null
+ });
+ } catch (err) {
+ this._errorMsg = err.message;
+ }
+
+ this._loading = false;
+ }
+}
+
+customElements.define('ha-change-password-card', HaChangePasswordCard);
diff --git a/src/panels/profile/ha-panel-profile.js b/src/panels/profile/ha-panel-profile.js
index db807828fd..85101e4e48 100644
--- a/src/panels/profile/ha-panel-profile.js
+++ b/src/panels/profile/ha-panel-profile.js
@@ -8,6 +8,8 @@ import { PolymerElement } from '@polymer/polymer/polymer-element.js';
import '../../components/ha-menu-button.js';
import '../../resources/ha-style.js';
+import './ha-change-password-card.js';
+
import EventsMixin from '../../mixins/events-mixin.js';
/*
@@ -51,6 +53,7 @@ class HaPanelProfile extends EventsMixin(PolymerElement) {
>Log out
+
`;