Currently I have my password TextFormField like this: 
TextFormField(
  decoration: const InputDecoration(
         
        
Thank @Parikshit Chalke for answer. However,
setState is quite expensive call if your only want to update your TextFormField and IconButton. Instead, wrap it inside StatefulBuilder and have only child items updated.
Example solution:
import 'package:flutter/material.dart';
class MyWidget extends StatefulWidget {
  @override
  _MyWidgetState createState() => _MyWidgetState();
}
class _MyWidgetState extends State {
  // initially password is invisible
  bool _passwordVisible = false;
  String _password;
  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        // other widget that does not need update when password visibility is toggled
        Text("I do not require update"),
        
        StatefulBuilder(builder: (_context, _setState) {
          // only following widget gets update when _setState is used
          return TextFormField(
            decoration: InputDecoration(
              suffixIcon: IconButton(
                icon: Icon(
                  _passwordVisible ? Icons.visibility : Icons.visibility_off,
                ),
                onPressed: () {
                  // use _setState that belong to StatefulBuilder
                  _setState(() {
                    _passwordVisible = !_passwordVisible;
                  });
                },
              ),
              labelText: 'Password',
              icon: const Padding(
                padding: const EdgeInsets.only(top: 15.0),
                child: const Icon(Icons.lock),
              ),
            ),
            validator: (val) => val.length < 6 ? 'Password too short.' : null,
            onSaved: (val) => _password = val,
            obscureText: true,
          );
        }),
      ],
    );
  }
}